Unity3D小白的第一个项目《简陋版坦克大战》
个人制作,仅供参考。。。
大家好,我是Unity3d游戏开发的小白一名,我对游戏开发有非常浓厚的兴趣,所以我学习了关于Unity3d游戏开发的一些知识。运用自己一些浅薄的见解开发了这个项目,现在想和大家分享一下。
(ps:游戏场景中的人物模型是在网上下载的,其余由本人完成。)
一、坦克的移动
玩家可以通过键盘控制坦克的前后移动和左右转向
void Move()
{
transform.Rotate(0, Input.GetAxis("Horizontal") * Time.deltaTime * speed * 6, 0);
transform.Translate(0, 0, Input.GetAxis("Vertical") * Time.deltaTime * speed);
}
写出来一个Move函数,函数中获取transform(坦克)的坐标轴,之后在update里面直接调用,玩家可通过键盘的w,a,s,d操控坦克。
二、人物角色的移动
人物角色的移动不再通过获取坐标轴控制,而是使用鼠标点击场景地面让人物到达指定位置。点击选中整个地面,这里面用到一个组件Nav Mesh Agent。在Navigation面板中根据情况对参数进行调整,最后点击Bake渲染。
注意,这是对场景中的地面进行的操作,不是人物角色。
首先是人物角色的移动,通过人物模型和坦克模型之间的碰撞检测实现人物开坦克的效果
三、敌方坦克的自动巡航和自动攻击
自动巡航
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI ;
public class Test : MonoBehaviour {
// Use this for initialization
void Start () {
cubeAgent.SetDestination (p1.position);
}
public Transform p1, p2;
public NavMeshAgent cubeAgent;
// Update is called once per frame
void Update () {
if(Vector3.Distance(cubeAgent.transform.position,p1.position)<2)
cubeAgent.SetDestination (p2.position);
if(Vector3.Distance(cubeAgent.transform.position,p2.position)<2)
cubeAgent.SetDestination (p1.position);
}
}
自动攻击
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotationTest : MonoBehaviour {
public Quaternion origDir;
// Use this for initialization
void Start () {
origDir = transform.rotation;
speed = 10;
fireRate = 2;
//tank = GameObject.Find("AItanke");
}
public Collider[] contectList;
public Transform target;
public Transform spownpoint;
public RaycastHit hit;
public Ray ray;
public GameObject paodan;//炮弹预制体
public Transform paodanSpownpoint;//炮弹生成的地方
public float speed;
public float fireRate;//开炮间隔时间
public float fireTime;
void Update () {
ray = new Ray (spownpoint.position, transform.TransformDirection (Vector3.forward));
Physics.Raycast (ray , out hit);
contectList = Physics.OverlapSphere (transform.position, 32);
Debug .DrawRay (spownpoint.position, (GameObject .Find ("player").transform .position -spownpoint .position )*20);
foreach (Collider i in contectList) {
if (i.CompareTag ("Player") && hit.collider != null && hit.collider.CompareTag ("Player")) {
Quaternion dir = Quaternion.LookRotation (target.position - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, dir, Time.time * 0.1f);
//tank.GetComponent<AIContrllor>().Fire();
Fire();
}
if(hit.collider==null||!hit.collider.CompareTag ("Player"))
transform.rotation = Quaternion.Slerp (transform.rotation, origDir, Time.time * 0.001f);
}
}
void OnDrawGizmos(){
Gizmos.DrawWireSphere (transform.position, 30);
}
public void Fire()
{
if (Time.time > fireTime + fireRate)
{
GameObject tmpPaodan = Instantiate(paodan, paodanSpownpoint.position, Quaternion.identity);
tmpPaodan.GetComponent<Rigidbody>().AddForce(paodanSpownpoint.forward * 2000);
fireTime = Time.time;
}
}
}
四、粒子系统的触发
首先需要自己创建粒子系统组件,然后对其参数进行调整
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AItanke_lizi : MonoBehaviour {
// Use this for initialization
void Start () {
}
public ParticleSystem buff3;//定义一个粒子系统名叫buff3
// Update is called once per frame
void Update () {
}
void OnCollisionEnter(Collision other)//碰撞检测
{
if (other.transform.CompareTag("paodan"))//对所碰撞的物体进行比较标签
{
buff3.Play();
}
}
}
五、库房的开关门动画
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Door : MonoBehaviour
{
// Use this for initialization
void Start()
{
CHU = GameObject.Find("chu");
JIN = GameObject.Find("jin");
JIN.SetActive(true);
HOU = GameObject.Find("hou");
HOU.SetActive(true);
}
public NavMeshAgent tanke;
public Animation mendonghua;
public ParticleSystem buff2;
public GameObject CHU;
public GameObject JIN;
public GameObject HOU;
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter(Collider other)
{
if (other.name == "jin")
{
mendonghua["Take 001"].speed = 1;
mendonghua["Take 001"].time = 0;
mendonghua.Play();
CHU.SetActive(false);
Invoke("guanmen", 3);
Debug.Log("101010");
}
if (other.name == "zhong")
{
CHU.SetActive(true);
JIN.SetActive(false);
//Debug.Log("000");
}
if (other.name == "hou")
{
JIN.SetActive(true);
//CHU.SetActive(false);
Debug.Log("000");
}
if (other.name == "chu")
{
mendonghua["Take 001"].speed = 1;
mendonghua["Take 001"].time = 0;
mendonghua.Play();
Invoke("guanmen", 3);
}
if (other.name == "buff1")
{
buff2.Play();
//Debug.Log("1111111");
}
}
void guanmen()
{
mendonghua["Take 001"].speed = -1;
mendonghua["Take 001"].time = mendonghua["Take 001"].length;
mendonghua.Play("Take 001");
}
}
六、炮弹数量及血量计数(包括UI界面显示)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
// Use this for initialization
void Start()
{
ammoCount = 0;
speed = 10;
Emery_flood = 20;
My_flood = 10;
}
public Text ammoCountdisplay;
public Text EmeryfloodDisplay;
public Text MyfloodDisplay;
public int ammoCount;
public GameObject paodan;
public Transform paodanSpownpoint;
public float speed;
public int zonggong;
public int Emery_flood;
public int My_flood;
public bool move_tanke;
public GameObject AIThirdPersonController;
public Camera ren_touding;
// Update is called once per frame
void Update()
{
Fire();
if (move_tanke)
Move();
ammoCountdisplay.text = "炮弹数:" + zonggong + "/" + ammoCount;
EmeryfloodDisplay.text = "敌方血量:" + Emery_flood;
MyfloodDisplay.text = "我方血量:" + My_flood;
}
void Move()
{
transform.Rotate(0, Input.GetAxis("Horizontal") * Time.deltaTime * speed * 6, 0);
transform.Translate(0, 0, Input.GetAxis("Vertical") * Time.deltaTime * speed);
}
void Fire()
{
if (Input.GetKeyDown(KeyCode.R))
{
if (ammoCount > 0)
{
zonggong += 30;
ammoCount -= 30;
}
}
if (zonggong > 0)
if (Input.GetKeyDown(KeyCode.Space))
{
GameObject tmpPaodan = Instantiate(paodan, paodanSpownpoint.position, Quaternion.identity);
tmpPaodan.GetComponent<Rigidbody>().AddForce(paodanSpownpoint.forward * 2000);
zonggong--;
}
}
void OnTriggerEnter(Collider other)
{
if (other.name == "buff1")
{
if (ammoCount < 120)
ammoCount += 30;
}
}
private void OnCollisionEnter(Collision other)
{
if (other.collider.name == "AIThirdPersonController")
{
AIThirdPersonController.SetActive(false);
move_tanke = true;
ren_touding.gameObject.SetActive(false);
}
}
}
七、总体效果
简陋版坦克大战总体效果