zoukankan      html  css  js  c++  java
  • unity案例入门(二)(坦克大战)

    1. 案例简述

    这个案例实现一个简单的坦克对战游戏,两个玩家在一个地图上PK。

    2. 控制坦克移动

    与案例一中小球的移动方式不同,坦克在横向上不能是平移,因此横向按键控制的应该是坦克旋转。

    public float speed = 5;//前进速度
    public float angularSpeed = 5;//旋转速度
    private Rigidbody rd;
    
    void Start () {
    	rd = this.GetComponent<Rigidbody> ();
    }
    
    void FixedUpdate(){
    	float v = Input.GetAxis ("VerticalPlayer" + number);//自定义虚拟轴
    	rd.velocity = transform.forward * v * speed;//根据情况需要在刚体组件Constraints冻结相应position或rotation
    
    	float h = Input.GetAxis ("HorizontalPlayer" + number);
    	rd.angularVelocity = transform.up * h * angularSpeed;
    }
    

    (1)与Update()不同,Update()方法是游戏每渲染一帧调用一次,调用的频率会受机器影响,而FixedUpdate()是每隔一定时间间隔调用一次,调用的频率不受机器影响。因此,为了得到更逼真的物理效果,在模拟物理运动时,一般选择在FixedUpdate()中。

    (2)由于游戏中有两个玩家,asdw和方向键需要控制两个不同角色,因此需要自定义虚拟轴,位置是:Edit->Project Setting->Input。

    (3)根据实际情况,需要在刚体组件中的Constraints进行相应的Freeze操作。

    3. 控制子弹发射

    public class TankAttack : MonoBehaviour {
    
    	public GameObject shellPrefab;//子弹的预设
    	public KeyCode fireKey = KeyCode.Space;//发射子弹的按键
    	public float shellSpeed = 15;//子弹射出速度
    	private Transform firePosition;//发射子弹的位置
    
    	void Start () {
    		firePosition = transform.Find ("FirePosition");
    	}
    	
    	void Update () {
    		if (Input.GetKeyDown(fireKey)) {
    			GameObject go = GameObject.Instantiate (shellPrefab, firePosition.position, firePosition.rotation) as GameObject;//生成子弹
    			go.GetComponent<Rigidbody> ().velocity = go.transform.forward * shellSpeed;//发射子弹
    		}
    	}
    }
    

    生成子弹的位置是坦克炮筒处,因此在该处新建一个空对象,调整其旋转角度,这个对象的transform即可作为生成子弹的transform。

    public class Shell : MonoBehaviour {
    
    	public GameObject shellExplosionPrefab;
    
    	...
    
    	void OnCollisionEnter(Collision collision){
    		GameObject.Instantiate (shellExplosionPrefab, transform.position, transform.rotation);
    		GameObject.Destroy (this.gameObject);//若传入参数为this,则值销毁当前脚本而非游戏对象
    	}
    }
    

    对子弹进行碰撞检测(触发检测也可以,区别在于爆炸前有无撞击效果),当子弹击中物体时即在当前位置生成爆炸特效,同时销毁子弹对象。

    public class DestroyForTime : MonoBehaviour {
    
    	public float time;//在检视面板传入该特效的播放时长
    
    	void Start () {
    		Destroy (this.gameObject, time);//播放完毕后销毁
    	}
    }
    

    给爆炸特效增加脚本,当特效播放完毕后销毁对象。

    4. 子弹击中坦克产生伤害

    在子弹击中坦克后,主要处理在坦克的生命值上,因此在子弹的碰撞检测中发送消息,而后在坦克中进行处理。

    if (collision.collider.tag == "Tank") {
    	collision.collider.SendMessage ("TakeDamage");//若击中坦克,则发送消息
    }
    

    给坦克增加一个单独的脚本进行生命值的控制:

    public class TankHealth : MonoBehaviour {
    
    	public GameObject tankExposionPrefab;
    	public int health = 100;
    
    	void TakeDamage(){
    		health -= Random.Range (10, 20);
    		if (health <= 0) {
    			GameObject.Instantiate (tankExposionPrefab, this.transform.position, this.transform.rotation);
    			GameObject.Destroy (this.gameObject);
    		}
    	}
    }
    

    5. 双主角的情况下控制相机跟随、视野缩放

    public class FollowTarget : MonoBehaviour {
    
    	public Transform player1;
    	public Transform player2;
    
    	private Camera camera;
    	private Vector3 offset;
    
    	void Start () {
    		camera = this.GetComponent<Camera> ();
    		offset = transform.position - (player1.position + player2.position) / 2;
    	}
    	
    	void Update () {
    		transform.position = (player1.position + player2.position) / 2 + offset;
    		float distance = Vector3.Distance (player1.position, player2.position);
    		float size = distance;
    		camera.orthographicSize = size;//让正交相机视野实时改变
    	}
    }
    

    (1)双角色的相机跟随本质上与单角色没太大区别,只是将视点定在两个角色的中心点,通过中心点计算相机的偏移量,实时更新相机的position。

    (2)视野的缩放则是利用了正交相机的size与两个角色之间的距离之比进行更改,案例中两角色之间初始距离为10,相机size为10,因此比例为1,所以直接让size = distance。

    6. 控制声音播放

    AudioSource.PlayClipAtPoint (tankExposionAudio, this.transform.position);
    

    第一种方法,播放获得的AudioClip对象,第一个参数为AudioClip对象,第二个参数为播放位置。

    第二种方法,为游戏对象添加一个AudioSource组件,在脚本中通过GetComponent()方法获得该组件,调用其play()方法进行播放。

    案例下载 密码:z79o

  • 相关阅读:
    HDU-1225 Football Score
    HDU-3854 LOOPS
    HDU-3863 No Gambling
    poj-2096 Collecting Bugs
    HDU-4336 Card Collector
    HDU-4405 Aeroplane chess
    2010上交:最小面积子矩阵
    VijosP1443:银河英雄传说
    VijosP1250:分组背包
    Vijos1221:神秘的配方
  • 原文地址:https://www.cnblogs.com/joahyau/p/6938973.html
Copyright © 2011-2022 走看看