C# 在两个方向上旋转玩家控制的门
重要提示: 我在这里开始发帖 我在与它交互时创建了一个全自动门 现在我想要一扇门,由玩家打开,由玩家关闭。您可以设置一个门,使门始终旋转远离玩家 调用方法C# 在两个方向上旋转玩家控制的门,c#,unity3d,C#,Unity3d,重要提示: 我在这里开始发帖 我在与它交互时创建了一个全自动门 现在我想要一扇门,由玩家打开,由玩家关闭。您可以设置一个门,使门始终旋转远离玩家 调用方法interactive()时,门将开始旋转。我从另一个脚本调用此方法。因此,在这一时刻,该方法只调用一次 [SerializeField] Vector3 openRotation; // door rotation when opened [SerializeField] float duration; // ope
interactive()
时,门将开始旋转。我从另一个脚本调用此方法。因此,在这一时刻,该方法只调用一次
[SerializeField]
Vector3 openRotation; // door rotation when opened
[SerializeField]
float duration; // opening speed (duration)
[SerializeField]
bool isClosable; // door can be closed again?
[SerializeField]
Vector3 pivotPosition; // position of the pivot point
[SerializeField]
bool opensAwayFromPlayer; // always open away from the player
bool isActive = false; // door is "busy" ?
Transform doorPivot;
Transform playerTransform;
bool isOpen = false;
private void Start()
{
playerTransform = Globals.GetPlayerObject().transform;
doorPivot = new GameObject().transform;
doorPivot.position = pivotPosition;
transform.SetParent(doorPivot);
}
public void Interact() // Interact with the door and start opening / closing it
{
StartCoroutine(DoorRotation());
}
void IEnumerator DoorRotation()
{
if (isActive) // return if already active
yield break;
isActive = true;
float counter; // current rotation counter
Vector3 defaultAngles = doorPivot.eulerAngles;
Vector3 desiredRotation = this.openRotation; // the target rotation
if (opensAwayFromPlayer && PlayerIsBehindDoor(transform, playerTransform)) // if behind door -> change direction
desiredRotation = -desiredRotation;
Vector3 openRotation = transform.eulerAngles + desiredRotation; // the final rotation
if (!isOpen) // open if closed
{
counter = 0;
while (counter < duration)
{
counter += Time.deltaTime;
LerpDoorRotation(doorPivot, defaultAngles, openRotation, counter, duration); // open the door
yield return null;
}
if (!isClosable) // if not closing again, destroy the script
Destroy(this);
}
else // close the door
{
counter = duration;
while (counter > 0)
{
counter -= Time.deltaTime;
LerpDoorRotation(doorPivot, defaultAngles, openRotation, counter, duration); // close the door
yield return null;
}
}
isOpen = !isOpen; // Toggle door state
isActive = false; // Door is not "busy"
}
bool PlayerIsBehindDoor(Transform door, Transform player) // Check if the player is in front or behind the door
{
Vector3 doorTransformDirection = door.forward.normalized;
Vector3 playerTransformDirection = (player.position - door.position).normalized;
return Vector3.Dot(doorTransformDirection, playerTransformDirection) < 0;
}
void LerpDoorRotation(Transform doorPivot, Vector3 defaultAngles, Vector3 targetRotation, float counter, float duration) // Door Rotation
{
doorPivot.eulerAngles = Vector3.Lerp(defaultAngles, targetRotation, counter / duration);
}
[序列化字段]
矢量3开放旋转;//门打开时的旋转
[序列化字段]
浮动持续时间;//开启速度(持续时间)
[序列化字段]
布尔不可关闭;//门可以再关上吗?
[序列化字段]
矢量3枢轴位置;//轴心点的位置
[序列化字段]
bool opensAwayFromPlayer;//始终向远离玩家的方向打开
bool isActive=false;//门“忙”了吗?
改造门轴;
变换播放变换;
bool-isOpen=false;
私有void Start()
{
playerTransform=Globals.GetPlayerObject().transform;
doorPivot=新游戏对象();
门枢轴位置=枢轴位置;
transform.SetParent(doorPivot);
}
public void Interact()//与门交互并开始打开/关闭它
{
开始例行程序(门旋转());
}
void IEnumerator门旋转()
{
if(isActive)//如果已激活则返回
屈服断裂;
isActive=true;
浮点计数器;//当前旋转计数器
Vector3默认角度=门枢轴.eulerAngles;
Vector3 desiredRotation=this.openRotation;//目标旋转
if(opensAwayFromPlayer&&PlayerIsBehindDoor(transform,playerTransform))//如果在门后->改变方向
desiredRotation=-desiredRotation;
Vector3 openRotation=transform.eulerAngles+desiredRotation;//最终旋转
if(!isOpen)//关闭时打开
{
计数器=0;
while(计数器<持续时间)
{
计数器+=时间增量时间;
LerpOrrotation(门枢轴、默认角度、打开旋转、计数器、持续时间);//打开门
收益返回空;
}
if(!isClosable)//如果不再关闭,请销毁脚本
摧毁(这个);
}
否则就关门
{
计数器=持续时间;
而(计数器>0)
{
计数器-=Time.deltaTime;
LerpOrrotation(门枢轴、默认角度、打开旋转、计数器、持续时间);//关门
收益返回空;
}
}
isOpen=!isOpen;//切换门状态
isActive=false;//门不“忙”
}
bool PlayerIsBehindDoor(转换门,转换玩家)//检查玩家是在门前还是门后
{
Vector3 doorTransformDirection=door.forward.NORMATED;
Vector3播放器传输方向=(player.position-door.position)。标准化;
返回向量3.Dot(门变换方向、播放器变换方向)<0;
}
void LerpDoorRotation(变换门枢轴、向量3默认角度、向量3目标、浮动计数器、浮动持续时间)//门旋转
{
doorPivot.eulerAngles=Vector3.Lerp(默认角度、目标、计数器/持续时间);
}
所以这扇门有一个非常奇怪的行为。开关不正确。我创建了一个gif,显示与门交互时的行为
门会打开两次,然后更改其目标角度