发布时间:2025-12-10 19:12:01 浏览次数:16
3D坦克大战_大型3D单机版游戏Unity学习记录_unity3d坦克大战
从unity store中下载所需资源内含坦克模型、弹药模型、地图模型…然后将资源导入unity
主要包括三个文件夹1、Scripts2、Prefabs3、Scenes希望我今天分享的这篇文章可以帮到您。
添加Rigidbody刚体
模拟炮弹物理作用,有质量和重力。
Add Component->Physics->RigidBody
添加Collider碰撞体
Add Component->Physics->Capsule Collider(胶囊碰撞体)
调整胶囊的轴向、高度、半径以贴合炮弹模型
添加炮弹爆炸粒子(particles)特效
从资源中找到爆炸特效拖入shell对象中
1、右键Hierarchy中的预制件->Prefabs->unpack2、成功(Hierarchy中字体由蓝变白),这样对物体的操作就不会有干扰3、将Hierarchy中处理好的预制件拖入Project中自己创建的文件夹Prefabs中添加RigidBody刚体
添加Box Collider碰撞体
坦克分上下两部分,添加两个碰撞体以贴合坦克形状
添加坦克粒子爆炸特效
添加坦克血条
1、添加UI控件:右键Tank->UI->Slider(滑动块)
2、 Fill Area的Fill Rect改为full,360°,Fill移入Slider并删除Fill Area
3、Background和Fill图片都设为圆环
Background和Fill坐标全部置零使二者重合
调色
Slider设为长宽4×4大小
做成预制件拖入Prefabs文件夹
1、Window->Rendering->Lighting进入光源设置2、在Environment Lighting将Source的SkyBox改为Color3、在Scene->Lighting Settings-->new Lighting Settings4、LightingMapping Seethings将LightingMapper设为Enlighten5、Lighting Mode设为Subtractive6、删除原先场景光照 //对象声明过后要实例化才能使用 //变量名不要使用rigidbody,这个命名在基类中存在所以会被隐藏继承,除非加new--用下划线区分开 public Rigidbody _rigidbody; // Start is called before the first frame update void Start() { //this指这个脚本,此脚本的游戏对象(挂载到Tank),获取此游戏对象身上的RigidBody组件 _rigidbody = gameObject.GetComponent<Rigidbody>();//新版本不必加this }Input管理器 public float speed = 2;//速度 public float rotateSpeed = 2;//转速 void Update() { //结合Input控制器 h_Value = Input.GetAxis("Horizontal1");//a,d--转弯 v_Value = Input.GetAxis("Vertical1");//s,w--前进后退 if (v_Value != 0)//为正,前进,为负,后退 { _rigidbody.MovePosition(this.transform.position + v_Value*this.transform.forward * speed * Time.deltaTime);//Time.deltaTime--上一帧执行的时间/每帧的间隔时间 } //转弯 if(h_Value!=0) { if(v_Value<0) { h_Value = -h_Value;//转弯逻辑 } this.gameObject.transform.Rotate(Vector3.up * h_Value * rotateSpeed * Time.deltaTime); } }避免坦克翻车public enum TankType{ Tank_One=1, Tank_Two=2, Tank_Enemy=3,} public TankType tankType = TankType.Tank_One;//坦克1 public string inputHorizontalStr; public string inputVerticalStr;//使输入方式可变,wasd和上下左右void Start() { //this指这个脚本,此脚本的游戏对象(挂载到Tank),获取此游戏对象身上的RigidBody组件 _rigidbody = gameObject.GetComponent<Rigidbody>();//新版本不必加this inputHorizontalStr = inputHorizontalStr + (int)tankType; //在unity面板中输入Horizontal和Vertical,自动根据坦克1或2来赋值Horizontal1/2和Vertical1/2 inputVerticalStr = inputVerticalStr + (int)tankType; } void Update() { //结合Input控制器 h_Value = Input.GetAxis(inputHorizontalStr;//a,d--转弯 v_Value = Input.GetAxis(inputVerticalStr);//s,w--前进后退 } public GameObject[] tanks;//两个坦克的数组 public Vector3 targetCameraPos = Vector3.zero; public Camera mainCamera; public Vector3 currentVelocity = Vector3.zero;//初始化 public float smoothTime = 0.1f;//平滑时间 public float maxSmoothSpeed = 2; // Start is called before the first frame update void Start() { mainCamera = Camera.main;//初始化 } void Update() { ResetCameraPos(); } void ResetCameraPos() { //1、计算相机移动的位置 //2、平滑移动相机 Vector3 sumPos=Vector3.zero;//初始化 foreach(var tank in tanks)//tanks中的每一辆坦克 { sumPos += tank.transform.position;//坦克的位置全部相加 } if(tanks.Length>0) { targetCameraPos= sumPos / tanks.Length;//算出相机移动目标位置 targetCameraPos.y = mainCamera.transform.position.y;//避免y坐标偏差 mainCamera.transform.position = Vector3.SmoothDamp(mainCamera.transform.position, targetCameraPos, ref currentVelocity, smoothTime, maxSmoothSpeed); //当前位置,目标位置,速度 } }}初始化坦克数组,在初始化坦克处赋值
Tank设置Tag为Player
public RyumnCameraControl cameraControl;//使运行后才出现的Tank(Clone)赋值给坦克数组 // Start is called before the first frame update void Start() { TankSpwan();//初始化 if(cameraControl!=null) { cameraControl.tanks = GameObject.FindGameObjectsWithTag("Player");//查找复制后坦克的tag } }先初始化生成坦克,再为坦克赋值
相机尺寸修改 void ResetCameraSize() { //通过计算相机与坦克中心的位置的x和z差值,来计算size值 //勾股 float size = 0; foreach(var tank in tanks) { Vector3 offSetPos = tank.transform.position - targetCameraPos; //坦克位置减去两坦克中心位置 float z_Value = Mathf.Abs(offSetPos.z);//绝对值 size = Mathf.Max(size, z_Value);//z方向取最大值 float x_Value = Mathf.Abs(offSetPos.x); size = Mathf.Max(size, x_Value/mainCamera.aspect); } mainCamera.orthographicSize = size;//正交模式下相机的size }优化相机位置 public AudioSource bgm; public AudioSource tankExplosion; public AudioSource shellExplosion; public AudioSource tankFire;游戏开始时播放bgmvoid Update() { audioManager = GameObject.FindWithTag("AudioManager").GetComponent<RyumnAudioManager>(); //为音频管理添加Tag,使用Tag查找 if(audioManager!=null) { audioManager.bgmAudioPlay(); } }坦克发射炮弹音效 //爆炸音效 public AudioSource shellFireAudio; public AudioSource shellExplosionAudio; void Start() { //坦克开火音效 if (shellFireAudio != null) { if (!shellFireAudio.isPlaying) { shellFireAudio.Play(); } } } //炮弹爆炸音效 if (shellExplosionAudio != null) { shellExplosionAudio.gameObject.transform.parent = null;//父物体设为null if (!shellExplosionAudio.isPlaying) { shellExplosionAudio.Play(); Destroy(shellExplosionAudio.gameObject, 1); } }炮弹爆炸音效会跟随炮弹被销毁,因此听不见
将炮弹爆炸音效做粒子特效同样处理
public void ShellDamage(float damage) { if(PH<=0) { Invoke("ReloadTankBattleScene", 2); } } void ReloadTankBattleScene() { SceneManager.LoadScene("3DTanksBattle"); }