如果这些内容对你有用,请做一棵蒲公英让知识的种子随风植入人的心里。
在下篇中我们将讲解UI界面的关系与玩家在场景中陷阱交互的机制。
另外给大家推荐一个做动画不错的插件叫做DOTween,http://dotween.demigiant.com/documentation.php.
UIBaseScript:主要作为UI界面的父类,其中包含场景进入,场景暂停,场景重置,场景结束四个功能,另外需要给预制体UI添加CanvasGroup组件以便我们控制场景的射线检测,交互,透明度等信息。
UIBaseScropt:
protected CanvasGroup canvasGroup;
public virtual void Awake()
{
canvasGroup = GetComponent<CanvasGroup>();//获取CanvasGroup组件
}
public virtual void Enter() { } //UI入栈
public virtual void Pause() { } //UI暂停
public virtual void Resume() { } //UI重置
public virtual void Exit() { } //UI出栈
UIStartScript:继承自父类UIBaseScript//用了DOTWEEN插件记得引入命名空间using DG.Tweening
public class UIStartScript : UIBaseScript {
private Button OptionButton;
private Button StartButton;
public override void Awake()
{
base.Awake();//调用父类awake方法
Debug.Log("UIStart Awake");
}
void Start()
{
OptionButton = transform.Find("BG/Option").GetComponent<Button>();
OptionButton.onClick.AddListener(GoOption);
StartButton = transform.Find("BG/Play").GetComponent<Button>();
StartButton.onClick.AddListener(GoPlay);
}
public override void Enter()
{
//Debug.Log("UIStart Enter");
//canvasGroup.alpha = 0.5f;
//打开UI界面的交互
canvasGroup.interactable = true;
//开启UI简便动画(0-1)
canvasGroup.DOFade(1,0.5f);
//打开射线检测
canvasGroup.blocksRaycasts = true;
}
public override void Pause()
{
//关闭UI界面的交互
canvasGroup.interactable = false;
//开启UI简便动画(1-0)
canvasGroup.DOFade(0, 0.5f);
//关闭射线检测
canvasGroup.blocksRaycasts = false;
}
public override void Resume()
{
//打开UI界面的交互
canvasGroup.interactable = true;
//开启UI简便动画(0-1)
canvasGroup.DOFade(1, 0.5f);
//打开射线检测
canvasGroup.blocksRaycasts = true;
}
public override void Exit()
{
}
void GoOption()
{
//从start跳转设置界面
UIManager.Instance.Load("Option");
}
void GoPlay()
{
//跳转关卡界面
UIManager.Instance.Load("Level1");
}
UIOption:选项界面,主要控制音乐播放与返回主页面
public class UIOption : UIBaseScript {
Button backBtn;
Button muteBtn;
Image muteImage;
private bool isMute;//bgm是静音
private Sprite mute_on;
private Sprite mute_off;
public override void Awake()
{
base.Awake();
}
void Start()
{
backBtn = transform.Find("BG/Back").GetComponent<Button>();
backBtn.onClick.AddListener(GoBack);
muteBtn = transform.Find("BG/bg/Music/Button").GetComponent<Button>();
muteBtn.onClick.AddListener(ControllBGM);
muteImage = transform.Find("BG/bg/Music/Button").GetComponent<Image>();
mute_on = muteImage.sprite;
mute_off = Resources.Load<Sprite>("UI/Switch_off");
}
public override void Enter()
{
//打开UI界面的交互
canvasGroup.interactable = true;
//开启UI简便动画(0-1)
canvasGroup.DOFade(1, 0.5f);
//打开射线检测
canvasGroup.blocksRaycasts = true;
}
public override void Pause()
{
}
public override void Resume()
{
}
public override void Exit()
{
//把当前脚本所在的游戏物体给删除
//先隐藏界面 关闭交互
canvasGroup.interactable = false;
canvasGroup.DOFade(0, 0.5f);
//关闭射线检测
canvasGroup.blocksRaycasts = false;
}
void GoBack()
{
UIManager.Instance.Pop();
}
void ControllBGM()
{
isMute = !isMute;
AudioManager.Instance.Mute = isMute;
if(isMute)
{
muteImage.sprite = mute_off;
}
else
{
muteImage.sprite = mute_on;
}
}
}
UILose:插件控制结束界面的进出进入与CanvasGroup功能
public class UILose : UIBaseScript {
Transform lose;
Button replayBtn;
Vector3 originalPos;
public override void Awake()
{
lose = transform.Find("Panel/Lose").transform;
originalPos = lose.position;
replayBtn = lose.Find("RePlay").GetComponent<Button>();
replayBtn.onClick.AddListener(Replay);
base.Awake();
}
public override void Enter()
{
Debug.Log(lose);
lose.DOLocalMoveY(0,0.5f);
canvasGroup.interactable = true;
canvasGroup.blocksRaycasts = true;
}
public override void Exit()
{
lose.position = originalPos;
canvasGroup.interactable = false;
canvasGroup.blocksRaycasts = false;
}
public void Replay()
{
UIManager.Instance.Pop();
}
}
UILevel1:给摄像机添加CameraFollow脚本进行镜头跟随与重置退出关卡等
public class UILevel1 : UIBaseScript {
CameraFollow cf;
public override void Awake()
{
base.Awake();
}
public override void Enter()
{
Debug.Log("开始游戏了");
if(cf ==null)
{
cf = Camera.main.gameObject.AddComponent<CameraFollow>();
}
cf.enabled = true;
}
public override void Resume()
{
Debug.Log("重新开始当前关卡");
//1.重置人物的状态
Hero.instance.Reset();
//2.重置关卡中的每个陷阱中的ResetLevel脚本 执行rest方法
ResetLevel[] res = FindObjectsOfType<ResetLevel>();
for(int i=0;i<res.Length;i++)
{
res[i].Rest();
}
}
public override void Exit()
{
cf.enabled = false;
}
}
Hero:玩家的移动跳跃等,需要判断玩家是否在地面(不能连跳),玩家是否死亡等状态。
public static Hero instance;
Rigidbody2D rig;
public float speed = 5;
public float force = 300;
private bool dead;
//玩家位置
public Vector3 SavePos
{
get;
set;
}
public bool isFly
{
get;
set;
}
public bool isDead
{
get
{
return dead;
}
set
{
dead = value;
if(dead)
{
//ToDo处理hero的事件
//退出Lose界面
UIManager.Instance.Load("UILose");
}
}
}
private void Awake()
{
instance = this;
}
void Start (){
rig = GetComponent<Rigidbody2D>();
SavePos = transform.position;
stone1 = GameObject.Find("Stone1").transform.position;
stone2 = GameObject.Find("Stone2").transform.position;
stone3 = GameObject.Find("Stone3").transform.position;
stone4 = GameObject.Find("Stone4").transform.position;
leftsword = GameObject.Find("LeftSword").transform;
rightsword = GameObject.Find("RightSword").transform;
leftswordPos = leftsword.transform.position;
rightswordPos = rightsword.transform.position;
}
void Update (){
Motion();
}
void Motion()
{
if(isDead)
{
Debug.Log("英雄死了");
rig.velocity = Vector2.zero;
return;
}
//虚拟轴控制左右移动
float hor = Input.GetAxis("Horizontal");
//Hero添加一个速度
rig.velocity = new Vector2(hor*speed,rig.velocity.y);
//按下空格键跳跃
if(Input.GetKeyDown(KeyCode.Space) && !isFly )
{
rig.AddForce(Vector2.up * force);
}
}
//重置玩家状态
public void Reset()
{
transform.position = SavePos;
isDead = false;
//重置人物的动画
}
重点来袭!!三大事件(碰撞,触发,还原陷阱)
当玩家掉到地图下或者碰到能主动攻击玩家的怪物时候,会调用碰撞事件监测机制,造成玩家死亡!
public class CollisionEvent : MonoBehaviour {
public UnityEvent collisionEvent;
public bool HeroIsFly;
void OnCollisionEnter2D(Collision2D other)
{
HeroIsFly = false;
Hero.instance.isFly = HeroIsFly;
collisionEvent.Invoke();
}
private void OnCollisionExit2D(Collision2D other)
{
HeroIsFly = true;
Hero.instance.isFly = HeroIsFly;
}
}
当玩家在固定位置踩到触发器,会触发相应事件,采用触发机制,如站在指定位置跳跃可顶出砖块
public class TriggerEvent : MonoBehaviour {
public UnityEvent triggerEvent;
public bool isDead;
private void OnTriggerEnter2D(Collider2D other)
{
//当Hero触发陷阱的时候调用triggerEvent
triggerEvent.Invoke();
Hero.instance.isDead = isDead;
}
}
当玩家死亡时,点击重置按钮,玩家会回到初始位置,这时候把玩家触发出来的陷阱反向触发回去,采用重置事件。
public class ResetLevel : MonoBehaviour {
public UnityEvent ResetEvent;
public void Rest()
{
ResetEvent.Invoke();
}
}
图片中对比两个脚本内容,当碰撞或者触发某个事件时,重置事件需要做的就是反向触发回去,如砖块图片为1,当碰撞图片编程2,重置事件就需要把图片在重置关卡的时候重置回1。
CameraFollow:最后一个相机跟随脚本,采用插值方式平滑处理,限制下X轴保持场景一致。
public class CameraFollow : MonoBehaviour {
Transform target;
void Start()
{
target = GameObject.Find("Hero").transform;
}
void LateUpdate () {
Follow();
}
void Follow()
{
//x [-0.2,23];
Vector3 pos = transform.position;
pos.x = Mathf.Lerp(pos.x,target.position.x,1);
pos.x = Mathf.Clamp(pos.x, -0.2f, 23);
transform.position = pos;
}
}
虽然只做了一个关卡,但是包括了整个游戏90%的内容,希望对你有所帮助。