Unity自动门笔记

学习目标:

提示:内容学习视频来源:B站

https://www.bilibili.com/video/BV1Jt4y1q7mn/?spm_id_from=333.880.my_history.page.click&vd_source=f3700c962af09e81e2314d3bd816d4a1

例如:

  • 理解与运用C#中的事件
    事件的五要素:
    本期代码对应
  • 1.拥有事件的类  --EventSystem
    2.事件的响应者  --Door
    3.事件                 --OnDoorEnter,OnDoorExit
    4.事件的订阅      +=DoorOpen,+=DoorClose
    5.事件处理器      方法

学习内容:

自动门

1.在开始前需要准备一个新场景,并且创建一个空物体存放触发碰撞体(BoxCollider组件),并将其碰撞体的IsTriger勾选
2.代码部分与准备:加入LeanTween插件

3.代码部分:
Door

using UnityEngine;
public class Door:MonoBehaviour
{
  [SerializeField] private int doorID;//记录ID,为游戏对象与触碰的门单独触发
  [SerializeField] private float MoveHeith = 3.7f;//门的移动高度,这里可以根据场所自定意
  [SerializeField] private float StartPos;
pulic void Start()//订阅事件
{
  EventSystem.instance.OnDoorEnter += DoorOpen;
  EventSystem.instance.OnDoorExit += DoorClose;
}

private viod OnDestory() //取消订阅,这里是扩展需求如果需要破坏门
{
  EventSystem.instance.OnDoorEnter -= DoorOpen;
  EventSystem.instance.OnDoorExit -= DoorClose;
}
  //如果两个事件的处理器方法订阅事件的话,那么他们的返回值和参数列表,必须保持“类型兼容”
  //事件是使用的Action的委托,我们的这两个方法,返回值必须为空,参数列表为空
public void DoorOpen(int _id )
{
  if(doorID = _id)
  LeanTween.moveLocalY(gameObject,MoveHeith,1.0f); //这里使用LeanTween插件
}
public void DoorClose(int _id)
{
 if(doorID = _id)
  LeanTween.moveLocalY(gameObject,StartPos,1.0f);
}
}

EventSystem代码:
 

using System;
using UnityEngine;


//事件的拥有者 ——EventSystem
public class EventSystem :MonoBehaviour
{
 public static EventSystem instance;
 private void Awake()  //单例
{
  if(instance == null)
  {
    instance =this;
  }
  if(instance != null)
  { 
    Destory(gameObject);
  }  
  DontDestoryOnLoad(gameObject);
}
 //声明事件
 public event Action<int> OnDoorEnter;
 public event Action<int> OnDoorExit;
 //事件外部是不能被直接调用的,是事件的拥有者的某些“内部逻辑”触发的
 public void OpenDoor(int _id)
  {
      if(OnDoorEnter != null)
      {
          OnDoorEnter(_id);
      }
  }
 public void CloseDoor(int _id)
  {
      if (OnDoorExit != null)
      {
          OnDoorExit(_id);
      }
  }
}

TriggerArea脚本:

using UnityEngine;

public class TriggerArea : MonoBehaviour
{
 [SerializeField] private int AreaId;
 private void OnTriggerEnter(Collider other)
   {
    EventSystem.instance.OpenDoor(AreaId);
   }
 private void OnTriggerExit(Collider other)
   {
    EvenSystem.instance.CloseDoor(AreaId);
   }
}

PlayerMovement脚本:
 

using UnityEngine;
[requireComponent(typeof(Rigibody))]
public class PlayerMovement : MonoBehaviour
{
  public Rigibody rb;
  public float moveSpeed;
  private Vector3 moveInput;
  private void Start()
  { 
   rb = GetComponent<Rigibody>();
  }
  private void Update()
  {
   moveInput = new Vector3(Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical"));
   LookAtCursor();
  }
  
 private void LookAtCursor()
 { 
  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  Plane plane = new Plane(Vector3.up, Vector3.zero);
  float distToGround = 0;
  if(plane.Raycast(ray, out distToGround))  
  {
      Vector3 point = ray.GetPoint(distToGround);
      Vector3 rightPoint = new Vector3(point.x, transform.position.y, point.z);
      transform.LookAt(rightPoint);
  }
  
 private void FixedUpdate()
 {
     rb.MovePosition(rb.position + moveInput * moveSpeed * Time.deltaTime); 
 }
}

如果你还想控制门的不同的开门方向,可以如下书写
 

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


//事件的响应者:Door
//事件的处理器:DoorOpen() DoorClose()

 public enum Direction 
{
    AxisX, AxisY, AxisZ

}
public class Door : MonoBehaviour
{
    [SerializeField] private float toAmount, oriAmount;
    [SerializeField] private int doorID;
    [SerializeField] private float MoveHeith = 3.7f;
     public Direction direction;  //方向AxisX, AxisY, AxisZ
    private void Start()
    {
        EventSystem.instance.OnDoorEnter += DoorOpen;
        EventSystem.instance.OnDoorExit += DoorClose;
    }
    private void OnDestroy()
    { 
        EventSystem.instance.OnDoorEnter -= DoorOpen;
        EventSystem.instance.OnDoorExit -= DoorClose;
    }
    //如果两个事件的处理器方法订阅事件的话,那么他们的返回值和参数列表,必须保持“类型兼容”
    //事件是使用的Action的委托,我们的这两个方法,返回值必须为空,参数列表为空
    public void DoorOpen(int _id)
    {
        if (doorID == _id)
             // LeanTween.moveLocalY(gameObject, MoveHeith, 1.0f);
            switch (direction)
            {
              case Direction.AxisX:
                    LeanTween.moveLocalX(gameObject, toAmount, 1.0f).setEaseInQuad();
                   break;
              case Direction.AxisY:
                    LeanTween.moveLocalY(gameObject,toAmount, 1.0f).setEaseOutQuad();
                    break;
              case Direction.AxisZ:
                    LeanTween.moveLocalZ(gameObject, toAmount, 1.0f).setEaseOutQuad();
                    break;


            //}
    }
    public void DoorClose(int _id)
    {
        if(doorID == _id)
              //LeanTween.moveLocalY(gameObject, 1.25f, 1.0f);
            switch (direction)
            {
                case Direction.AxisX:
                   LeanTween.moveLocalX(gameObject, oriAmount, 1.0f).setEaseInQuad();
                    break;
               case Direction.AxisY:
                   LeanTween.moveLocalY(gameObject, oriAmount, 1.0f).setEaseOutQuad();
                    break;
               case Direction.AxisZ:
                   LeanTween.moveLocalZ(gameObject, oriAmount, 1.0f).setEaseOutQuad();
                   break;


            }
    }

}

Thank~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值