去年在校做的大创,结合AR做了一款雷霆战机的手游,时间太久了,还是打算整理一下核心玩法部分,核心玩法其实套用的是unity官方给出的space shooter的骨架,对应自己时间和需求将其简化和自主加工,由于纯自学还没开相应的课,所以有些知识点理解错误或不全还望各位大佬指正。
核心玩法中前部分是跟随网上一个博主做的中文版视频学习做的,大家可以去网上搜一下。
https://www.jianshu.com/p/8cc3a2109d3b 这是简书上的导入项目在unity资源商店就可导入,本项目适合小白学习
游戏模型有些违和不要在意,官网上是正常的飞机,游戏主要分为玩家,boss和陨石,由于是手游,导入了easytouch组件做的摇杆,建议想做手游的同学在测试时也要加上wasd移动,不然测试会非常受阻。其余胜利失败结算弹窗等就不上图了,等写到再上。
按照上述导入工程后首先把背景图添加进去
可以看到其实就在这里用了一个cube方块将背景图片放入。
看到左下角了吗,其实这些立体组件和ui是分开的,ui组件在创建的时候会自动加在canvas画板上,其实不难理解,ui组件是2d元素,和立体组件不属于同一纬度,ui组件会自适应game视图,做手游尤其注意一开始要定好game界面比例。
这个界面依次有主摄像机,敌机(boss),灯光,背景,边框(控制陨石销毁),游戏总控制(这其实是一个空物体,我们在它上面添加游戏背景音乐,变更几分文本,关联的弹窗等等),画板(所有unity自带ui组件都会默认创建在Canvas中),玩家,后面三个是导入的摇杆组件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour {
float changeValue = 0.2f;//单次变化量
float changeValue1 = 0.1f;//单次变化量
public Image green;
public RectTransform rectBloodPos;
private Rigidbody rb;
public float y_min;
public float y_max;
public float z_min;
public float z_max;
public float speed;
public int Maxlife; //玩家飞机最大生命值
public int Damage; //子弹伤害值
public int AsDamage;
public GameObject playerExplosion;
private GameController gc;
private GameObject gameControllerObject;
public GameObject asteroidExp;
public GameObject shotSpawn;
public GameObject shot;
private float myTime;
private float nextFire;
public float fireDelta;
void Start()
{
gameControllerObject = GameObject.FindGameObjectWithTag ("GameController");//用标签获取gameocontroller组件
gc=gameControllerObject.GetComponent<GameController>() ;//赋值,主要作用于玩家死亡或者得分时弹窗或动态修改文本
rb = GetComponent<Rigidbody> ();//获取刚体组件
}
//-6 +6 -8 +8
void FixedUpdate(){//wasd移动
float horizontalInput = Input.GetAxis ("Horizontal");
float verticalInput = Input.GetAxis ("Vertical");
rb.velocity = new Vector3 (0, verticalInput*speed, horizontalInput*speed);
rb.position = new Vector3 (
rb.position.x,
Mathf.Clamp (rb.position.y, y_min, y_max),//边距,设置最大最小移动范围,保证玩家不会飞出屏幕
Mathf.Clamp (rb.position.z, z_min, z_max)
);
rb.rotation = Quaternion.Euler (0, 0, /*-(rb.velocity.z * 5)*/0);//旋转,由于做的是yz轴游戏,所以在z轴旋转
}
void OnTriggerEnter(Collider other)//碰撞函数,unity原生函数,所有碰撞代码都写在这里,注意碰撞前要加碰撞体,后期会单独分块讲,这里主要用的都是tag判断
{
if (other.gameObject.CompareTag ("Bolt1")) {//如果碰到自己的子弹就穿过去,不会有任何影响
return;
}
if (other.gameObject.CompareTag ("Asteroid")) {//如果碰到陨石则进行判断
if (Maxlife > 0) {//血量大于0时
Maxlife -= AsDamage;//减掉陨石攻击的血
Change(green, -changeValue1);//更改血条(用的button这个组件做血条不太好,有兴趣可以去上网看一下做血条)
Destroy (other.gameObject);//毁灭这个陨石
Instantiate(asteroidExp, this.transform.position, Quaternion.identity);//实例化一个陨石爆炸效果
gc.addScore (10);//这里就用上了gameController里的加分函数,一个陨石传10分过去
}
else {//血量小于或等于0时
Destroy (other.gameObject);//毁灭陨石
Change(green, -changeValue1);//更改血条
gc.addScore (10);//得分
Destroy (this.gameObject);//毁灭自己
Instantiate (playerExplosion, other.transform.position, Quaternion.identity);//实例化一个飞机爆炸的效果
gc.gameOver ();//调用游戏结束函数
}
}
if (other.gameObject.CompareTag ("djbolt")) {//如果碰到的是敌机的子弹
if (Maxlife > 0) {
Maxlife -= Damage;
Change(green, -changeValue);
Destroy (other.gameObject);
}
else {
Destroy (other.gameObject);
Change(green, -changeValue);
Destroy (this.gameObject);
Instantiate (playerExplosion, other.transform.position, Quaternion.identity);
gc.gameOver ();
}
}
}
public void Change(Image image,float value)//血条更改函数,后期会详讲
{
image.fillAmount += value;
Debug.Log(11);
}
void Update()//unity原生函数,更新函数,会每一帧进行更新,计时器一定会放在这里
{
myTime = myTime + Time.deltaTime;//给myTime进行每帧赋值,让myTime一点一点增加
if (myTime > nextFire)//如果大于下次开火时间
{
nextFire = myTime + fireDelta;//给nextFire更新
Instantiate (shot, shotSpawn.transform.position, Quaternion.identity);//实例化一个子弹,子弹是在物体前单独加了一个cube上放置的,后期会详讲
nextFire = nextFire - myTime;//更新
myTime = 0.0F;//归0
}
//get ScreenPoint...Important
Vector2 vec2 = Camera.main.WorldToScreenPoint(this.gameObject.transform.position);//获取当前玩家位置,血量条跟随
rectBloodPos.anchoredPosition = new Vector2(vec2.x - Screen.width / 2 + 0, vec2.y - Screen.height / 2 + 100);
}
}
有关摇杆的代码都删掉了,等之后详解