U3D学习笔记二:3D坦克大战

来源:互联网 发布:scratch趣味编程100例 编辑:程序博客网 时间:2024/05/01 22:39

花了接近两天,试着将已近有的资源用上,开发出了一个简单的游戏。小小地总结下,理清下思路。要制作一个游戏,前期的准备是必不可少的,比如声音资源(AudioClips),一些模型(Models),一些材质(Materials)都是需要制作完成的,想要成为一个独立的游戏开发制作者,必须学会这些东西,比如建模的3dMax,玛雅之类的一些常用的软件,还必须有相当的美术功底。不过,在公司里大家都各司其职吧。
有了这些东西,那么就是要实现程序控制的问题了。
首先是将游戏场景布置好,将坦克模型拖入游戏场景中去,将车位的行走特效放到坦克模型下,使得特效属于坦克。
然后用刚体组件,控制小车行走和转向。在坦克TankMove类中,实现以下代码来控制小车的运动:

        public int Speed=10;        public int AngularSpeed=10;         public int NumControl = 1;//增加编号来控制不同的坦克        private Rigidbody _rigidboyCar;        void start()        {             _rigidboyCar = GetComponent<Rigidbody>();        }        void Updata()        {            //得到键盘上的方向输入,值在-1到1之间变化            //HorizontalPlayer1只能由这asdw几个键控制,HorizontalPlayer2由箭头方向键控制。详情见Eidit->project settings->input            float keyNumQh = Input.GetAxis("VerticalPlayer" + NumControl);               //velocity施加速度,transform.forward前后移动            _rigidboyCar.velocity = transform.forward * keyNumQh * Speed;            //左右            float keyNumZy = Input.GetAxis("HorizontalPlayer"+NumControl);            _rigidboyCar.angularVelocity = transform.up*keyNumZy*AngularSpeed;        }

然后在炮筒口位置添加一个空的游戏对象,以便在这里实例化子弹,,通过制定按键进行子弹的发射,在TankFire类中实现下面的代码:

`    private Transform _firePosition;//子弹位置    public GameObject Shell;//子弹    public KeyCode Key = KeyCode.Space;//space按键控制发射    public int FireSpeed = 15;//子弹速度void Start ()        {            _firePosition = transform.Find("FirePositon");//得到指定名字游戏对象的位置        }        void Update () {            if (Input.GetKeyDown(Key))//按键触发实例化            {                                  var shellFire= Instantiate(Shell, _firePosition.position, _firePosition.rotation) as GameObject ;//实例化,在指定位置创建子弹                if (shellFire != null)                    shellFire.GetComponent<Rigidbody>().velocity = transform.forward*FireSpeed;//通过刚体发射子弹            }        }

那么子弹可以发射了,但是发射出去并不爆炸,那么如何控制子弹的爆炸,以及触发爆炸特效?答案是,利用在子弹上添加Capule Collider组件,控制子弹的碰撞检测,另外给子弹添加刚体控件,控制子弹的下落,在ShellExplousion类中实现:

 public GameObject ShellExpol;//爆炸特效对象 //碰撞检测        public void OnTriggerEnter(Collider collider)        {            Instantiate(ShellExpol, transform.position, transform.rotation);//触发爆炸特效                        Destroy(this.gameObject);//销毁子弹            if (collider.tag=="TANK")               {            //如果子弹碰撞到的是坦克的话,给坦克发送消息,控制血量             collider.SendMessage("TakeDamege");            }        }

接下来,给坦克添加标签tag,以便于子弹判断子弹碰撞的是坦克,来控制坦克血量的扣减,最后坦克血量为0后,销毁目标坦克。在控制坦克血量的类TankHealth中,实现下面代码:

public float Hp = 100;public GameObject TankExplosion;[CanBeNull] public Slider HpSlider;//血条,其size为0到1,0为完全不填充,1为完全填充 private const float HpTotal = 100;  private float _size;//当前血量/100  private void TakeDamege()        {                       if (Hp <= 0)                return;            Hp -= Random.Range(0, 20);//0到20随机扣血            if (HpSlider != null) HpSlider.value = Hp / HpTotal;//血条减少            if (Hp<=0)//死亡,tank爆炸            {                               Instantiate(TankExplosion, transform.position+Vector3.up, transform.rotation);//当前坦克的位置                 Destroy(this.gameObject);             }         }

另外游戏中是两个坦克,如何控制相机跟随两个坦克呢?通过得到初始时,得到两个坦克之间与相机的偏移值,然后相机的位置等于偏移值加上两个坦克之间的值除2。在相机对象下,添加Follow类脚本(组件)中实现下面代码:

public Transform Player1;public Transform Player2; private Vector3 _offset; private  Camera _camera;  void Start ()        {            _offset = transform.position - (Player1.position + Player2.position)/2;//两个坦克间初始位置的偏移量,以后相机随时保持这个偏移量。            _camera = GetComponent<Camera>();        }        void Update ()        {            if (Player1==null||Player2==null ) return;          ;            transform.position = _offset + (Player1.position + Player2.position)/2;            float distance = Vector3.Distance(Player1.position, Player2.position);            float size = distance*0.58f;//两个坦克位置的距离和相机size的比例为0.4,可以使得相机size随着两者距离改变,从而可以看得清楚            if (size>=10)            {                _camera.orthographicSize = size;            }            else            {                _camera.orthographicSize = 10;            }        }

到这里,基本结束。主要有几点要注意:

  • 要在哪个游戏对象上实现特点功能,就在相应的游戏对象上添加组件。比如控制坦克移动,就子在坦克游戏对象下添加控制运动的脚本。
  • 有的功能类型,需要重复使用的游戏对象,可以将游戏对象保存成prefab
  • transform类可以得到位置,刚体组件可以控制运动,
  • collider.SendMessage(“消息名”);可以实现类间的消息传递
  • 在声明public变量的时候,可以将相应对象拖入相应位置,实现初始化。
    还有一些细节,在以后慢慢继续学吧。。
0 0