01 坦克大战介绍
此处见:http://www.icemaplen.com/archives/127
02 创建工程 场景
导入场景模型,去掉方向光。
将摄像机的【Projection】属性修改为【Orthographic】(正交)模式,这样可以使场景中的物体大小不随距离而改变。
并调整好摄像机的位置和方向以及【Size】。
03 给场景中添加坦克,控制坦克前后移动和旋转
给坦克添加刚体组件。
控制坦克移动的代码:
float v = Input.GetAxis("Vertical");
rigidbody.velocity = transform.forward * v * Speed;
float h = Input.GetAxis("Horizontal");
rigidbody.angularVelocity = transform.up * h * AngularSpeed;
如果想使用Input制作某种运动行为,要使用Input.GetAxis()方法。它能够返回来自键盘、控制器或鼠标平滑的并且可以设置的输入结果。使用Input.GetButton()方法只用于像事件之类的动作。不要将它用于移动动作。Input.GetAxis()方法可以使脚本代码更简洁。
它根据坐标轴名称返回虚拟坐标系中的值。例如
value = Input.GetAxis ("Horizontal");
按下[kbd]左右方向键[/kbd],或[kbd]A[/kbd]、[kbd]D[/kbd]键,value会由0渐变为1或-1,渐变的时间由sensitivity决定。不按的话该值为0。这种情况用于操纵杆输入和键盘输入。
transform.forwad以物体坐标系为准,表示该坦克的目前位置的正前方。
Speed是float类型的变量,代表速度。
rigidbody.velocity 表示刚体的速度。
rigidbody.angularVelocity表示刚体的角速度,此处transform.up表示绕着y轴旋转。
另外由于坦克只需要在一个平面(地面)上移动和旋转,所以锁定y轴的位置和x轴、z轴的旋转:
04 修改坦克控制的灵活性(增加坦克编号)
修改控制坦克移动的脚本:
public float TankNumber = 1; //坦克编号
float v = Input.GetAxis("VerticalPlayer" + TankNumber);
rigidbody.velocity = transform.forward * v * Speed;
float h = Input.GetAxis("HorizontalPlayer" + TankNumber);
rigidbody.angularVelocity = transform.up * h * AngularSpeed;
打开Edit-Project Settings-Input,将【Horizontal】和【Vertical】分别复制两份并重命名,分别代表两个坦克。
然后更改名字:
可以看到,在这里可以修改按键,默认是都有a,d,left,right,这表示a,d键和左右键都可以进行控制,所以要将【HorizontalPlayer1】的a,d删去,只留下left,right。表示只能通过左右键控制移动,同理删去【HorizontalPlayer2】的left,right,只留下a,d,表示只能通过a,d键控制移动。【VerticalPlayer1】和【VerticalPlayer2】同理修改。
05 控制坦克子弹的发射和飞行
GameObject go = GameObject.Instantiate(ShellPrefab, FirePosition.position, FirePosition.rotation) as GameObject;
go.GetComponent<Rigidbody>().velocity = transform.forward * ShellSpeed;
利用GameObject.Instantiate()方法生成子弹。
子弹添加刚体组件,并调用Rigidbody.velocity控制速度。此处和坦克的移动大致相同。
06 控制炸弹的爆炸和伤害判定
给坦克添加Tank标签。
void OnTriggerEnter(Collider coll)
{
//在碰撞处生成爆炸特效
GameObject.Instantiate(ShellExplosionPrefab, transform.position, transform.rotation);
//判断碰撞体是否是坦克
if(coll.tag == "Tank")
{
//如果碰到的是坦克,就发送受到攻击的消息
coll.SendMessage("TakeDamage");
}
//销毁子弹
GameObject.Destroy(this.gameObject);
}
坦克接受受到伤害消息:
void TakeDamage()
{
//如果hp小于0,游戏结束,什么也不做
if (hp <= 0) return;
//随机伤害
hp -= Random.Range(10, 20);
if(hp <= 0)
{
//坦克爆炸效果
GameObject.Instantiate(TankExplosionPrefab, transform.position + Vector3.up, transform.rotation);
//销毁坦克
GameObject.Destroy(this.gameObject);
}
}
07 控制相机视野跟随
public class FollowTarget_ : MonoBehaviour {
public Transform Tank1;
public Transform Tank2;
private Vector3 offset;
private Camera camera;
// Use this for initialization
void Start () {
offset = transform.position - (Tank1.position + Tank2.position) / 2;
camera = this.GetComponent<Camera>();
}
// Update is called once per frame
void Update () {
if (Tank1 == null || Tank2 == null) return;
transform.position = offset + (Tank1.position + Tank2.position) / 2;
float distance = Vector3.Distance(Tank1.position, Tank2.position);
float size = distance * 0.56f;
camera.orthographicSize = size;
}
}
这里主要有两处要点,
[infobox title=”一是使摄像机始终处于两个坦克中间”]此处先算出两个坦克的中间位置,再算出摄像机与 中间位置的偏移量,并在游戏中不断更新。[/infobox] [infobox title=”二是使摄像机的视野始终随着两个坦克距离发生变化”]首先在Unity中经过不断测试算出摄像机的视野大小最合适的数值为两个坦克之间距离的0.56倍,然后通过算法在游戏中不断计算坦克间位置,再乘以0.56,最后令摄像机视野大小保持这个数值就行了。[/infobox]07 游戏音效及UI
不写了,上课去。
1 comment
👿