刚学了Unity游戏开发,做了一个坦克大战。

最近这一个星期学了unity的脚本开发 和transform 刚体 碰撞器 触发器 这些组件。就用新学的知识做一个坦克大战吧。

项目资源在这里哦自取
链接:https://pan.baidu.com/s/1_5u4TKzCVpL4LtA4Ev6ayA
提取码:g12v
–来自百度网盘超级会员V2的分享
坦克大战

一: 首先。我们先用unity自带的组件搭建场景吧!场景
用plane和一些cube 做成了一个小范围。用圆柱体和两个cube搭建一个玩家坦克(player)
因为我们要有很多敌人,所有我们把敌人坦克做成预制件。
同样方法吧玩家的炮弹和敌人的炮弹也做成预制件

我们用子弹打敌人,子弹可以设置成触发器。

在这里插入图片描述
并把敌人加标签在这里插入图片描述
同样道理 敌人的炮弹打玩家,敌人的炮弹加触发器。玩家加标签。
好了我们的场景搭建就先说到这儿吧。

二:现在我们要实现的是玩家可以用过wsad控制移动和旋转。按空格可以开炮。此标题下脚本都挂载在player上

脚本:

public class TankPlayer : MonoBehaviour {
    private float hor;
    private float ver;
    private bool fire;//是否开炮
    public int life;
    [HideInInspector]
    public bool invincibleFlag;
    public float moveSpeed;
    public float turnSpeed;
    [Header("子弹预制件")]
    public GameObject bulletPlayer;
    private Vector3 bulletPos;
	void Start () {
        moveSpeed = 10;
        turnSpeed = 2;
        life = 100;
        invincibleFlag = false;
    }
	
	// Update is called once per frame
	void Update () {
        hor = Input.GetAxis("Horizontal"); 
        ver = Input.GetAxis("Vertical"); 
        fire = Input.GetButtonDown("Fire");
        transform.position +=  ver * transform.forward * moveSpeed * Time.deltaTime;
        this.transform.position = new Vector3(transform.position.x, 0, transform.position.z);
        transform.Rotate(Vector3.up * hor * turnSpeed);
        if (fire)
        {
            bulletPos = GameObject.Find("player/fire/firePos").transform.position;
            GameObject bullet = Instantiate(bulletPlayer,bulletPos,Quaternion.identity);
        }
        if (life <= 0)
        {
            Destroy(this.gameObject);
        }
	}
    private void FixedUpdate()
    {
        GetComponent<Rigidbody>().velocity = Vector3.zero;
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "wall")
        {
            transform.eulerAngles -= new Vector3(0, 180, 0);
        }
    }
    private void OnTriggerEnter(Collider other)
    {
     //   Debug.Log(other.gameObject.name);
        if (other.tag == "imprisoned")
        {
            Destroy(other.gameObject);
            GetComponent<InprisonedClass>().enabled = true;
        }
        if(other.tag== "invincible")
        {
            Destroy(other.gameObject);
            GetComponent<InvincibleClass>().enabled = true;
        }
        if (other.tag == "allDeid")
        {
            Destroy(other.gameObject);
            GetComponent<AllDeidClass>().enabled = true;
        }
    }

这里要说明的是,要提前去edit/projectSetting 中的Input中设置水平轴 竖直轴 开火键。
小细节:在碰撞检测中检测碰到墙就转头。
在触发器中检测,是否触发了 道具。其中道具是预制件。并且挂在了标签。如果触发了道具,将销毁道具对象,并且使道具的对应脚本启动,开始实现道具的功能

第一个道具是紧固所有敌人。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InprisonedClass : MonoBehaviour {
    private float time;
    private List<GameObject> enemys;
    private bool enemyCanMoveFlag;
	// Use this for initialization
	void Start () {
        time = 5;
        enemyCanMoveFlag = false;
        enabled = false;
	}
	// Update is called once per frame
	void Update () {
        time -= Time.deltaTime;
        GameObject[] enemys = GameObject.FindGameObjectsWithTag("enemy");
        if (time > 0)
        {
            enemyCanMoveFlag = false;
                        for (int i = 0; i < enemys.Length; i++)
            {
                enemys[i].GetComponent<EnemyControl>().enabled = enemyCanMoveFlag;
            }
        }
        else
        {
            enemyCanMoveFlag = true;
            time = 5;
            for (int i = 0; i < enemys.Length; i++)
            {
                enemys[i].GetComponent<EnemyControl>().enabled = enemyCanMoveFlag;
            }
            enabled = false;
        }
    }
}

这里是把控制敌人的方法设置为不可用,这样敌人就无法移动了。时间是五秒。五秒以后敌人就可以动了
执行完以后,再把这个方法禁用,等待下次触发禁锢道具时在启用。

第二个道具是使玩家无敌
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InvincibleClass : MonoBehaviour {
    private float time ;
	// Use this for initialization
	void Start () {
        time = 5;
        enabled = false;
	}
	// Update is called once per frame
	void Update () {
        time -= Time.deltaTime;
        if (time > 0)
        {
            this.gameObject.GetComponent<TankPlayer>().invincibleFlag = true;  
        }
        else
        {
            this.gameObject.GetComponent<TankPlayer>().invincibleFlag = false;
            time = 5;
            enabled = false;
        }
        
	}
}

这里是玩家无敌五秒。直接设置玩家是否无敌bool值为true,并在玩家类中进行判断。五秒后,设置玩家是否无敌为false 并设置此方法为false,等待下一次触发

第三个道具是 杀灭全场所有敌人。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AllDeidClass : MonoBehaviour {
    private GameObject[] enemys;
	// Use this for initialization
	void Start () {
        enabled = false;
	}	
	// Update is called once per frame
	void Update () {
        enemys = GameObject.FindGameObjectsWithTag("enemy");
        for (int i = 0; i < enemys.Length; i++)
        {
            Destroy(enemys[i].gameObject);

        }
        enabled = false;
	}
}

找到所有标签为敌人的对象 并且全部销毁。

三:敌人AI的生成和控制。
敌人AI的生成 脚本挂载在空对象或摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyLife : MonoBehaviour
{
    [Header("敌人预制件")]
    public GameObject enemyPrefab;
    private Vector3 positionEnemy;
    private float timeGenerate;
    private int num;
    // Use this for initialization
    void Start()
    {
         num = 25;
        timeGenerate = 3f;
    }
    private void LateUpdate()
    {
        timeGenerate -= Time.deltaTime;
        if ( timeGenerate< 0)
        {
            Generate();
            timeGenerate = 3;
        }

    }
    /// <summary>
    /// 生成坦克
    /// </summary>
    public void Generate()
    {
       
        if(num>0)
        {
            num--;
            do
            {
                positionEnemy = new Vector3(Random.Range(-48, -21), 1, Random.Range(48, 21));
            }
            while (false);
            Instantiate(enemyPrefab, positionEnemy, Quaternion.Euler(0, 180, 0));
        }

    }
    /// <summary>
    /// 这个位置能不能用
    /// </summary>
    /// <param name="pos">位置</param>
    /// <returns></returns>
    public bool CanotUsePos(Vector3 pos)
    {
       return Physics.CheckSphere(pos, 2, ~(1 << 8));
        
    }
}

在随机生成的时候 我们要随位置进行,物理检测,这个位置一定范围内不可以有其他敌人。CanotUsePos()方法中的Physics.CheckSphere(pos, 2, ~(1 << 8));是检测在pos的两米范围内,除了第八层的所有层的对象。
其中地板加layer,为第八层
在这里插入图片描述

敌人AI的控制 挂载在敌人上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyControl : MonoBehaviour {
    public GameObject bulletPerfab;
    private GameObject player;
    private Transform playerTransform;
    private float dis;
    private float timeBullet;
	// Use this for initialization
	void Start () {
        timeBullet = 0;
        dis = 0;
        gameObject.GetComponent<MoveEnemy>().flag = false;
    }
	
	// Update is called once per frame
	void Update () {
        player = GameObject.Find("player");
        
        playerTransform = player.transform;
        dis = Vector3.Distance(transform.position, playerTransform.position);
        if (dis > 20)
        {
            //TODO:坦克巡逻
            gameObject.GetComponent<MoveEnemy>().flag = true;
        }else if (dis < 20 && dis > 10)
        {
            //向前逼近
            gameObject.GetComponent<MoveEnemy>().flag = false;
            TurnToPlayer();
            GoToPlayer();
        }
        else if (dis < 10)
        {
            gameObject.GetComponent<MoveEnemy>().flag = false;
            //转向玩家开炮
            TurnToPlayer();
            FirePlayer();
        }
	}
    /// <summary>
    /// 逼近玩家
    /// </summary>
    private void GoToPlayer()
    {
       
        if (!ForwordHaveFriend())
        {
            this.transform.position += transform.forward * GetComponent<MoveEnemy>().speed * Time.deltaTime;
        }
        this.transform.position = new Vector3(transform.position.x, 1, transform.position.z);
    }
    /// <summary>
    /// 前方有敌人
    /// </summary>
    /// <returns>true:有false无</returns>
    private bool ForwordHaveFriend()
    {
         Ray ray = new Ray(transform.position, transform.forward * 3);
         if (Physics.Raycast(ray, 3, (1 << 9)))
         {
             return true;
         }
        return false;
    }
    private void FirePlayer()
    { 
        timeBullet -= Time.deltaTime;
        if (timeBullet < 0)
        {
            timeBullet = 3;
            Vector3 pos = transform.Find("fire/firePos").transform.position;
            GameObject bullet = Instantiate(bulletPerfab, pos, Quaternion.identity);
            bullet.GetComponent<BulletEnemy>().forword_Bullet = this.transform;
        }
    }
    private void TurnToPlayer()
    {
        Vector3 playerPos = player.transform.position;
        Quaternion target = Quaternion.LookRotation(playerPos - transform.position);
        transform.rotation = Quaternion.Lerp(transform.rotation, target, GetComponent<MoveEnemy>().smooth);
    }
}

其中MoveEnemy是巡逻类。

敌人AI的巡逻类 挂载在敌人上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveEnemy : MonoBehaviour {
    private float angle;
    public float speed;
    public float smooth;
    private float timeTurn ;
    [HideInInspector]
    public bool flag;
    //目标四元数
    Quaternion target;
    // Use this for initialization
    void Start () {
        smooth = 2;
        speed = 2;
        timeTurn = 1;
        flag = false;
    }	
	// Update is called once per frame
	void Update () {
        if (flag)
        {
            timeTurn -= Time.deltaTime;
            if (timeTurn < 0)
            {
                angle = Random.Range(0, 360);
                target = Quaternion.Euler(0, angle, 0);
                transform.rotation = Quaternion.Lerp(transform.rotation, target, smooth * Time.deltaTime);
                timeTurn = 0.5f;
            }
            GetComponent<Rigidbody>().velocity = Vector3.zero;

            this.transform.position += transform.forward * speed * Time.deltaTime;
            this.transform.position = new Vector3(transform.position.x, 1, transform.position.z);
        }
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "wall")
        {
            transform.eulerAngles -= new Vector3(0, 180, 0);
        }
    }
    private void FixedUpdate()
    {
        GetComponent<Rigidbody>().velocity = Vector3.zero;
    }
}
四:炮弹的脚本

玩家 的炮弹:挂载在玩家炮弹的预制件上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletPlayer : MonoBehaviour {
    public float speed;
    public Transform player;
    private Vector3 forword_Bullet;
	// Use this for initialization
	void Start () {
        speed = 20;
        player = GameObject.FindGameObjectWithTag("player").transform;
        forword_Bullet = player.forward;
        transform.GetComponent<Rigidbody>().velocity = forword_Bullet * speed;
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.transform.root.tag== "enemy")
        {
            Destroy(other.gameObject.transform.root.gameObject);
            Destroy(this.gameObject);
        }
        if (other.gameObject.tag == "wall" || other.gameObject.tag == "floor")
        {
            Destroy(this.gameObject);
        }
    }
}

敌人的炮弹 挂载在敌人炮弹的预制件上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletEnemy : MonoBehaviour {
    public float speed;
    public Transform forword_Bullet;
    // Use this for initialization
    void Start () {
        speed = 20;
        transform.GetComponent<Rigidbody>().velocity = forword_Bullet.forward * speed;
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.transform.root.tag == "player")
        {
            if (!other.transform.root.GetComponent<TankPlayer>().invincibleFlag)
            {
                other.transform.root.GetComponent<TankPlayer>().life -= 1;
                Destroy(this.gameObject);
            }
        }
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "wall" || collision.gameObject.tag == "floor")
        {
            Destroy(this.gameObject);
        }
    }
}
五:摄像机跟随 脚本挂载在摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class followComera : MonoBehaviour {
    public float upDis;
    public float backDis;
    public float turnSpeed;
    private Vector3 positionC;
    private Transform follow;
	// Use this for initialization
	void Start () {
        upDis = 10;
        backDis = 20;
        turnSpeed = 2;
        follow = GameObject.FindWithTag("player").transform;
    }
	
	// Update is called once per frame
	void Update () {
        positionC = follow.position + upDis * Vector3.up - backDis * follow.forward;
        transform.position = Vector3.Lerp(transform.position, positionC, turnSpeed * Time.deltaTime);
        transform.LookAt(follow);
	}
}

六:生成道具的脚本,挂载在空对象或摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Prop : MonoBehaviour {
    private float timeP;
    /// <summary>
    /// 无敌
    /// </summary>
    public GameObject invinciblePrefab;
    public GameObject allDiedPrefab;
    /// <summary>
    /// 禁锢
    /// </summary>
    public GameObject imprisonedPrefab;
    private float hight;
    // Use this for initialization
    void Start () {
        timeP = 0;
        hight = GameObject.Find("hightProp").transform.position.y;
	}
	
	// Update is called once per frame
	void Update () {
        timeP -= Time.deltaTime;
        if (timeP <= 0)
        {
            timeP = 5;
            int x = Random.Range(-20, 20);
            int z = Random.Range(-20, 20);
            int num = Random.Range(1, 100);
            if (num <=50 && num > 1)
            {
                Instantiate(imprisonedPrefab, new Vector3(x, hight, z), Quaternion.identity);
            }else if (num > 50 && num <= 90)
            {
                Instantiate(invinciblePrefab, new Vector3(x, hight, z), Quaternion.identity);
            }else if (num > 90 && num <= 95)
            {
                Instantiate(allDiedPrefab, new Vector3(z, hight, z), Quaternion.identity);
            }
        }
	}
}

好了 我们的坦克大战开发完成了 看一下效果吧。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值