哎,掘金这都没多少关于Unity的技术博客,应该没人看到这篇文章了
感动,掘金官方竟然回复我了【哭了】
立刻附上素材链接:pan.baidu.com/s/1KiucZebe…
源码我再修改修改 加上注释 到时候再附上图片或者视频 力争做好这篇博客
- 导入素材
- 创建Scenes文件夹,保存当前场景
- 将游戏地形拖入层级视图
- 删除灯光,因为该地形自带灯光
- 关闭Lighting选项卡下的自动渲染,因为场景较大,耗时
- 根据个人喜好设置天空盒或者纯色天空(主摄像机处和Lighting选项卡处)
- 将坦克模型拖入场景中,重置位置
- 调整主摄像机的位置,并切换到正交模式
- 将冒烟预制体放到坦克的齿轮后头
- 将坦克做成预制体
- 为坦克添加碰撞器组件和刚体组件,碰撞器不要与地面重合
- 为坦克创建移动脚本,要把坦克刚体禁用y轴位置与x、z轴旋转
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankMovement : MonoBehaviour {
private Rigidbody rigidbody;
public float speed = 15f;
public float angularSpeed = 5f;
void Start () {
rigidbody = this.GetComponent<Rigidbody>();
}
// 物理更新函数
void FixedUpdate()
{
// 获得输入
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
// 前后移动
rigidbody.velocity = transform.forward * v * speed;
// 旋转
rigidbody.angularVelocity = transform.up * h * angularSpeed;
}
}
复制代码
- 给坦克炮台添加旋转脚本,注意添加一个新的输入轴,名为Rotation,选择按键控制,设为q与e键
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankRotation : MonoBehaviour {
public float rotationSpeed = 3f;
private float angle = 0;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// 用鼠标和按键同时控制旋转
float mousex = Input.GetAxisRaw("Rotation") == 0 ? Input.GetAxisRaw("Mouse X") : Input.GetAxisRaw("Rotation");
angle += mousex * rotationSpeed;
angle = angle < -360 ? angle += 360 : angle;
angle = angle > 360 ? angle -= 360 : angle;
angle = Mathf.Clamp(angle, -360, 360);
}
void LateUpdate()
{
Quaternion xQuat = Quaternion.AngleAxis(angle, transform.up);
transform.rotation = xQuat;
}
}
复制代码
- 将子弹模型拖入场景,添加胶囊碰撞器和刚体,碰撞器方向调为Z轴,大小适中,做成预制体后删除
- 在炮台下创建一个空物体,作为发射子弹的位置,位置调到炮台口,方向旋转成发射方向
- 给坦克添加攻击脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankAttack : MonoBehaviour {
// 子弹生成位置
public Transform firePosition;
// 子弹预制体
public GameObject shellPrefab;
// 子弹速度
public float shellSpeed = 15f;
void Update () {
// 空格键与鼠标左键
if (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Mouse0))
{
// 生成子弹并发射
GameObject shell = GameObject.Instantiate(shellPrefab, firePosition.position, firePosition.rotation) as GameObject;
shell.GetComponent<Rigidbody>().velocity = shell.transform.forward * shellSpeed;
}
}
}
复制代码
- 给子弹添加销毁脚本,将子弹设为触发器,将爆炸效果设为play on awake
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShellDestroy : MonoBehaviour {
// 爆炸效果
public GameObject shellExplosion;
public void OnTriggerEnter(Collider collider)
{
// 实例化爆炸效果
GameObject.Instantiate(shellExplosion, transform.position, transform.rotation);
// 销毁子弹自身
Destroy(this.gameObject);
}
}
复制代码
- 给爆炸效果添加销毁脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExplosionDestroy : MonoBehaviour {
// 消失时间
public float destroyTime = 1.5f;
void Start () {
Destroy(this.gameObject, destroyTime);
}
}
复制代码
- 设置坦克标签为Tank
- 修改子弹脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShellDestroy : MonoBehaviour {
// 子弹爆炸效果
public GameObject shellExplosion;
public void OnTriggerEnter(Collider collider)
{
// 给坦克造成伤害
if (collider.tag == "Tank")
{
collider.SendMessage("TakeDamage");
}
// 实例化爆炸效果
GameObject.Instantiate(shellExplosion, transform.position, transform.rotation);
// 销毁子弹自身
Destroy(this.gameObject);
}
}
复制代码
- 给坦克新建一个生命脚本,注意爆炸效果设为play on awake
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankLife : MonoBehaviour {
// 坦克总血量
public float hp = 100;
// 坦克爆炸效果
public GameObject tankExplosion;
// 伤害函数
void TakeDamage()
{
// 随机扣血
hp -= Random.Range(10, 20);
// 爆炸
if (hp <= 0)
{
GameObject.Instantiate(tankExplosion, transform.position, transform.rotation);
Destroy(this.gameObject);
}
}
}
复制代码
- 复制一个坦克,修改颜色,命名为Enemy,失效所有控制脚本,除了生命脚本
给摄像机添加视角跟随脚本还是不用脚本吧,将摄像机调整到坦克后上方,将其作为炮台的子物体
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowTank : MonoBehaviour {
public Transform player;
private Vector3 offset;
// Use this for initialization
void Start () {
offset = transform.position - player.position;
}
void Update () {
transform.position = player.position + offset;
}
}
复制代码