Unity records - ITween, Dotween realize opening and closing doors, judging whether they are in front of the door or behind the door, batch processing of single-opening, double-opening and sliding doors

1. Implementation of ITween method

using JetBrains.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using static iTween;

public enum DoorType
{
    ROTATE = 0,  //旋转门
    MOVE = 1,    //推拉门
}

public class MoveAndRotateController : MonoBehaviour
{

    //设置临时值用于存储初始位置
    Vector3 origPosition = Vector3.zero;

    [Header("门类型")]
    public DoorType doorType;
    [Header("公共属性")]
    public Transform Agent;
    Vector3 Temp;
    public float time;
    public float delayTime;
    public iTween.EaseType easeType;
    public iTween.LoopType loopType;
    //门是否已开
    public bool isOpen = false;
    //动画是否正在播放
    public bool isEnd = true;

    private void Start()
    {
        _isLock = false;
        switch (doorType) 
        {
            case DoorType.ROTATE:
            Temp = transform.eulerAngles;
                break;
            case DoorType.MOVE:
            Temp = transform.position;
                break;
        }

    }
    //public Transform Player;

    public void OpenDoor()
    {
        if (!isOpen && isEnd)
        {
            switch (doorType)
            {
                case DoorType.ROTATE:
                    //旋转门开门

                    RotateTo(Agent.eulerAngles, time, delayTime, easeType, loopType);

                    break;
                case DoorType.MOVE:
                    //移动门开门

                    MoveTo(Agent.position, time, delayTime, easeType, loopType);
                    break;
            }
            isOpen = true;
        }
        else
        {
            switch (doorType)
            {
                case DoorType.ROTATE:
                    //旋转门关门
                    RotateTo(Temp, time, delayTime, easeType, loopType);
                    break;
                case DoorType.MOVE:
                    //移动门关门
                    MoveTo(Temp, time, delayTime, easeType, loopType);
                    break;
            }

            isOpen = false;
        }
    }


    //添加移动
    public void MoveTo(Vector3 vec, float time, float delayTime, iTween.EaseType easetype, iTween.LoopType looptype)
    {
        iTween.MoveTo(gameObject, iTween.Hash("position", vec,
                                               "time", time,
                                               "delay", delayTime,
                                               "easetype", easetype,
                                               "looptype", looptype,
                                               "onstart", "StartTarget",
                                               "oncomplete", "CompleteTarget"
                                               ));
    }
    //添加旋转角
    public void RotateTo(Vector3 vec, float time, float delayTime, iTween.EaseType easetype, iTween.LoopType looptype)
    {
        iTween.RotateTo(gameObject, iTween.Hash("rotation", vec,
              "time", time,
              "delay", delayTime,
              "easetype", easetype,
              "looptype", looptype,
              "onstart", "StartTarget",
              "oncomplete", "CompleteTarget"
              ));
    }

    //开始播放动画
    public void StartTarget()
    {
        isEnd = false;
    }

    //动画播放结束
    public void CompleteTarget()
    {
        isEnd = true;
    }

    / <summary>
    / 判断玩家在物体的哪一面,正面返回true,背面返回false
    / </summary>
    / <returns></returns>
    //public bool PlayerPosition()
    //{
    //    float val = Vector3.Dot(transform.position - Player.position, transform.position - new Vector3(transform.position.x, transform.position.y, 1));
    //    //if (val <= 0)
    //    //{
    //    //    print("在门后");
    //    //}
    //    //else 
    //    //{
    //    //    print("在门前");
    //    //}
    //    bool isFront = val <= 0 ? false : true;
    //    return isFront;
    //    //Debug.DrawLine(new Vector3(transform.position.x,transform.position.y,1), transform.transform.position,Color.red);
    //    //Debug.DrawLine(Player.position, transform.transform.position,Color.blue);
    //}

}

 

 door handle swivel

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


public class RotateHandle : MonoBehaviour
{
    //设置临时值用于存储初始位置
    public Vector3 Vec;
    [Header("公共属性")]
    public float time;
    public float delayTime;
    public iTween.EaseType easeType;
    public iTween.LoopType loopType;

    bool _isLock = false;

    private void Start()
    {
        _isLock = false;
    }
    //把手
    public void Handle()
    {
        if (!_isLock) 
        {
            _isLock = true;
            RotateAdd(Vec, time, 0, easeType, loopType);
            RotateAdd(-Vec, time, 0.3f, easeType, loopType);
            StartCoroutine(IsLock());
        }
    }

    IEnumerator IsLock() 
    {
        yield return new WaitForSeconds(2 * time + 0.3f);
        _isLock = false;
    }
    //添加旋转角
    public void RotateAdd(Vector3 vec, float time, float delayTime, iTween.EaseType easetype, iTween.LoopType looptype)
    {
        iTween.RotateAdd(gameObject, iTween.Hash("amount", vec,
              "time", time,
              "delay", delayTime,
              "easetype", easetype,
              "looptype", looptype,
              "islocal", true
              ));
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(EventTrigger))]
[RequireComponent(typeof(MoveAndRotateController))]
public class DoorUser : MonoBehaviour
{
    EventTrigger eventTrigger;

    public MoveAndRotateController[] Door, Handle = null;

    private void Awake()
    {
        eventTrigger = GetComponent<EventTrigger>();
        AddPointerEvent(eventTrigger, EventTriggerType.PointerEnter, PointerEnter);
        AddPointerEvent(eventTrigger, EventTriggerType.PointerClick, PointerClick);
        AddPointerEvent(eventTrigger, EventTriggerType.PointerExit, PointerExit);
    }

    private void PointerClick(BaseEventData arg0)
    {
        print("Click");
        for (int i = 0; i < Door.Length; i++)
        {
            Door[i].OpenDoor();
            if (Handle.Length != 0)
                Handle[i].Handle();
        }

    }
    private void PointerExit(BaseEventData arg0)
    {
        
    }

    private void PointerEnter(BaseEventData arg0)
    {

    }

    //添加事件方法
    void AddPointerEvent(EventTrigger eventTrigger, EventTriggerType eventTriggerType, UnityEngine.Events.UnityAction<BaseEventData> callback)
    {
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventTriggerType;
        entry.callback = new EventTrigger.TriggerEvent();
        entry.callback.AddListener(callback);
        eventTrigger.triggers.Add(entry);
    }
}

 

 Implementation principle:

1. DoorDraft rotates towards the Euler angle y-axis value of Target, and records the original value. Trigger again to return to the original Euler angle. (Same for moving doors)

2. If there is a door handle that needs to be rotated, you also need to add the MoveAndRotateController.cs script to the door handle, and add the Obj of the handle to the Handle array of the DoorUser.cs script

 3. If it is a double door, add the MoveAndRotateController.cs script to the two doors and the two door handles, and give it to the Door and Handle arrays                                                  

Guess you like

Origin blog.csdn.net/weixin_46711336/article/details/128093260