控制相机视野跟随
本例只有2个坦克,所以控制视野在2个坦克中间即可
Main Camera 上挂载脚本 FollowTarget
public class FollowTarget : MonoBehaviour
{
public Transform player1; //路标1,unity中指定
public Transform player2; //路标2,unity中指定
private Vector3 offset; //Camera偏移
private Camera main_camera; //Camera组件
private float scale; //初始camera的size与player1、player2间的距离的比例
// Start is called before the first frame update
void Start()
{
// Camera初始位置 - (player1、player2 中心位置),得到的即为初始偏移量
offset = transform.position - (player1.position + player2.position) / 2;
// 获取到Camera组件
main_camera = this.GetComponent<Camera>();
// 初始camera的size与player1、player2间的距离的比例
scale = main_camera.orthographicSize / Vector3.Distance(player1.position, player2.position);
}
// Update is called once per frame
void Update()
{
//如果其中1个坦克被销毁,游戏结束,不再跟随,否则会出错
if (player1 == null || player2 == null) return;
// 每一帧都把player1、player2 中心位置加上初始偏移量就是相机的位置
transform.position = (player1.position + player2.position) / 2 + offset;
// player1、player2间的距离
float distance = Vector3.Distance(player1.position, player2.position);
// 通过camera的size与player1、player2初始比例计算当前比例下的size
float size = scale * distance;
// 设置main_camera的size,最小值为15
if (size > 15)
{
main_camera.orthographicSize = size;
}
}
}
给游戏添加音效
背景音乐:
创建个空物体,添加Audio Source,在AudioClip中选择bgm,勾选上Play On Awake和Loop即可
子弹发射,爆炸,坦克爆炸等音效,设置方式
......
public AudioClip nameAudio; //音效
......
// 触发事件后播放音效,播放位置,声音大小(可不填)
AudioSource.PlayClipAtPoint(nameAudio, transform.position, 1.0F);
然后在场景中的物体上在绑定的脚本中添加上音效文件
坦克添加音效
静止时音效
Tank预制体添加Audio Source,在AudioClip中选择相关的音效(EngineIdle),勾选上Play On Awake和Loop即可
行动时音效改变,在TankMovement中修改
public class TankMovement : MonoBehaviour
{
public float speed = 5; //移动速度
public float angularSpeed = 10; //旋转速度(10度)
public float number = 1; //编号
public AudioClip idleAudio; //停止时音效
public AudioClip drivingAudio; //行动时音效
private AudioSource audio; //声音组件
private Rigidbody rigidbody;
void Start()
{
rigidbody = this.GetComponent<Rigidbody>();
audio = this.GetComponent<AudioSource>();
}
void FixedUpdate()
{
float horizontal = Input.GetAxis("HorizontalPlayer" + number); //获取水平轴的偏移量
float vertical = Input.GetAxis("VerticalPlayer" + number); //获取垂直轴的偏移量
rigidbody.velocity = transform.forward * vertical * speed; //速度
rigidbody.angularVelocity = transform.up * horizontal * angularSpeed; //旋转
// 按住shift时快速移动
if (number == 1 && Input.GetKey(KeyCode.LeftShift))
{
rigidbody.velocity = transform.forward * vertical * 1.8f * speed;
}
// 按住+时快速移动
if (number != 1 && Input.GetKey(KeyCode.Plus))
{
rigidbody.velocity = transform.forward * vertical * 1.8f * speed;
}
// 偏移量的绝对值大于0.1就算移动了
if (Mathf.Abs(horizontal) > 0.1f || Mathf.Abs(vertical) > 0.1f)
{
audio.clip = drivingAudio;
if (audio.isPlaying == false) audio.Play();
}
else
{
audio.clip = idleAudio;
if (audio.isPlaying == false) audio.Play();
}
}
}
给坦克添加血条控制
新建一个UI组件:Slider,删除HandleSlideArea这个小圆点
设置下一Slider大小为40,把Background、Fill的背景图片Source Image设置为希望使用的图片
把Background、Fill Area、Fill填充模式都设置为最后一个,充满容器,把所有的Left、Top、Pos Z、Right、Bottom都设置为0
设置Fill(血条的颜色)为红色
Fill的Image Type设置为Filled(360度填充)
把Canvas的Render Mode设置为World Space(世界空间)
把Canvas的高宽设置为40,其下的Slider的postion设置为0
然后把Canvas整体移动到Tank里面,然后把位置归0(Y适当的上移一下,否则会被地面遮住)
调整大小为3,然后把Slider填充设置为布满全部,Left、Top、Pos Z、Right、Bottom设置为0
调整Canvas的Rotation中的X为90,让血条在坦克底部
全部设置好后,Prefab中Apply All应用到全部预制体上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //别忘了添加这个
public class TankHealth : MonoBehaviour
{
public int hp = 100; //坦克血量
public GameObject tankExplosion; //坦克阵亡效果
public AudioClip tankExplosionAudio; //坦克阵亡音效
public Slider hpSlider; //hp的Slider
private int hpTotal; //总血量
// Start is called before the first frame update
void Start()
{
hpTotal = hp;
}
// Update is called once per frame
void Update()
{
}
// 坦克受到伤害
void TankDamage()
{
if (hp <= 0) return; // 已阵亡
hp -= Random.Range(5, 15); //每次受到伤害损失5~15一个随机的伤害
hpSlider.value = (float)hp / hpTotal; //把其中一个int转成float这样计算后自动是个小数
if (hp <= 0)
{
// 坦克阵亡后播放音效,在当前位置播放
AudioSource.PlayClipAtPoint(tankExplosionAudio, transform.position, 1.0F);
// 受到伤害后阵亡,播放坦克阵亡动画 TankExplosion
// TankExplosion 的 Play On Awake 勾选上,被实例化后自动播放
GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation); // 为了效果,爆炸动画向上移动1米 + Vector3.up
GameObject.Destroy(this.gameObject); // 销毁掉坦克自身
}
}
}
写好后把挂载在Tank上TankHealth的脚本中的hpSlider赋值(之前做好的Slider血条),然后Prefab中Apply All应用到全部预制体上