該腳本有兩個狀態 NoEntry 和 NoExit。
第一個問題是TextToShow。當玩家進入/退出對撞機時,它在文本中顯示相同的文本。所以我將 textToShow 變數更改為陣列型別:
public string[] textToShow;
然后根據狀態 NoEntry/NoExit 我使用了 TextToShow[0] 和 TextToShow
我想要做的是為每個對撞機創建,例如玩家進入或退出對撞機,在這種情況下我可能在游戲中有 10 個對撞機,所以如果玩家擊中對撞機以識別對撞機并添加一些屬性在檢查員中。
或者可能是另一種方式,但想法是為每個對撞機創建一個 TextArea 以便我可以輸入文本并在檢查器中查看對撞機或文本何時顯示。
與變數相同的概念:targetToRotateTowards 現在,當玩家退出/進入時,他將向后走并面向變數 targetToRotateTowards 中的物件旋轉,而不是我希望在每個對撞機中玩家將執行其他操作,例如,如果對撞機處于狀態是 NoExit 向后移動面向某個物件,但如果對撞機狀態為 NoEntry,則玩家應該向后移動 180 度而不是特定物件。
并且通常將腳本擴展為更通用的更多情況。
也許在很多情況下使用列舉?例如,如果玩家進入小型對撞機,他會墜毀而死,但如果他退出大型對撞機,玩家將面向物件向后旋轉。
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;
public class DistanceCheck : MonoBehaviour
{
public Transform targetToRotateTowards;
public float lerpDuration;
public float rotationSpeed;
[TextArea(1, 2)]
public string[] textToShow;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public ThirdPersonUserControl thirdPersonUserControl;
private Animator anim;
private float timeElapsed = 0;
private float startValue = 1;
private float endValue = 0;
private float valueToLerp = 0;
private bool startRotating = false;
private bool slowOnBack = true;
private bool exited = false;
private Vector3 exitPosition;
private float distance;
public string[] TextToShow { get => textToShow; set => textToShow = value; }
void Start()
{
anim = transform.GetComponent<Animator>();
}
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(targetToRotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
{
distance = Vector3.Distance(transform.position, exitPosition);
}
if (distance > 5 && slowOnBack)
{
slowOnBack = false;
StartCoroutine(SlowDown());
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "NoExit")
{
descriptionTextImage.SetActive(true);
text.text = TextToShow[0];
RepositionPlayer();
}
else if (other.tag == "NoEntry")
{
OnPlayerRepositioned();
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "NoExit")
{
OnPlayerRepositioned();
}
else if (other.tag == "NoEntry")
{
descriptionTextImage.SetActive(true);
text.text = TextToShow[1];
RepositionPlayer();
}
}
private void RepositionPlayer()
{
// Stuff that needs to happen to reposition the player
exited = true;
slowOnBack = true;
exitPosition = transform.position;
thirdPersonUserControl.enabled = false;
StartCoroutine(SlowDown());
}
private void OnPlayerRepositioned()
{
// stuff you need to do to clear the "repositioning" status
exited = false;
startRotating = false;
text.text = "";
descriptionTextImage.SetActive(false);
}
IEnumerator SlowDown()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed = Time.deltaTime;
yield return null;
}
if (exited)
{
yield return new WaitForSeconds(3f);
startRotating = true;
StartCoroutine(SpeedUp());
}
if (slowOnBack == false)
{
thirdPersonUserControl.enabled = true;
}
}
IEnumerator SpeedUp()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed = Time.deltaTime;
yield return null;
}
}
}
創建 ColliderInfo 類后,我添加到類的兩個屬性中,第二個是:
public Transform rotateTowards;
班上 :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColliderInfo : MonoBehaviour
{
[TextArea] public string onEnterText, onExitText;
public Transform rotateTowards;
}
然后在 DistanceCheck 腳本中,我洗掉了變數 targetToRotateTowards 并添加了一個私有 ColliderInfo 變數:
private ColliderInfo colliderInfo;
然后在 Start 創建實體:
void Start()
{
anim = transform.GetComponent<Animator>();
colliderInfo = new ColliderInfo();
}
并在 FixedUpdate 中使用它:
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(colliderInfo.rotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
問題是 rotateTowrads 是 Transform 型別,但如果我希望變換按度旋轉而不是面對 rotateTowards 變換?
更改后的完整距離檢查腳本:
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;
public class DistanceCheck : MonoBehaviour
{
public float lerpDuration;
public float rotationSpeed;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public ThirdPersonUserControl thirdPersonUserControl;
private Animator anim;
private float timeElapsed = 0;
private float startValue = 1;
private float endValue = 0;
private float valueToLerp = 0;
private bool startRotating = false;
private bool slowOnBack = true;
private bool exited = false;
private Vector3 exitPosition;
private float distance;
private ColliderInfo colliderInfo;
void Start()
{
anim = transform.GetComponent<Animator>();
colliderInfo = new ColliderInfo();
}
private void FixedUpdate()
{
if (startRotating)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(colliderInfo.rotateTowards.position - transform.position),
rotationSpeed * Time.deltaTime);
}
if (exitPosition != new Vector3(0, 0, 0) && slowOnBack)
{
distance = Vector3.Distance(transform.position, exitPosition);
}
if (distance > 5 && slowOnBack)
{
slowOnBack = false;
StartCoroutine(SlowDown());
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "NoExit")
{
descriptionTextImage.SetActive(true);
if (other.TryGetComponent(out ColliderInfo info))
{
text.text = info.onExitText;
}
RepositionPlayer();
}
else if (other.tag == "NoEntry")
{
OnPlayerRepositioned();
}
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "NoExit")
{
OnPlayerRepositioned();
}
else if (other.tag == "NoEntry")
{
descriptionTextImage.SetActive(true);
if (other.TryGetComponent(out ColliderInfo info))
{
text.text = info.onEnterText;
}
RepositionPlayer();
}
}
private void RepositionPlayer()
{
// Stuff that needs to happen to reposition the player
exited = true;
slowOnBack = true;
exitPosition = transform.position;
thirdPersonUserControl.enabled = false;
StartCoroutine(SlowDown());
}
private void OnPlayerRepositioned()
{
// stuff you need to do to clear the "repositioning" status
exited = false;
startRotating = false;
text.text = "";
descriptionTextImage.SetActive(false);
}
IEnumerator SlowDown()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed = Time.deltaTime;
yield return null;
}
if (exited)
{
yield return new WaitForSeconds(3f);
startRotating = true;
StartCoroutine(SpeedUp());
}
if (slowOnBack == false)
{
thirdPersonUserControl.enabled = true;
}
}
IEnumerator SpeedUp()
{
timeElapsed = 0;
while (timeElapsed < lerpDuration)
{
valueToLerp = Mathf.Lerp(endValue, startValue, timeElapsed / lerpDuration);
anim.SetFloat("Forward", valueToLerp);
timeElapsed = Time.deltaTime;
yield return null;
}
}
}
uj5u.com熱心網友回復:
雖然還有其他方法可以解決這個問題,但是通過擴展專案將所有資訊提供給播放器腳本等中心化方法也使其更難以控制。我可以建議您的最好方法是自己提供對撞機資訊,因此創建ColliderInfo
一個如下所示的腳本并將其放置在目標區域上。
public class ColliderInfo : MonoBehaviour
{
[TextArea] public string onEnterText, onExitText;
}
完成后,前往該區域呼叫每個對撞機的資訊就足夠了,同樣簡單,同樣高效!下面的代碼寫在播放器中,解決了這個問題。請記住,只需預制它們即可創建類似的對撞機。
private void OnTriggerEnter(Collider other)
{
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onEnterText);
}
}
private void OnTriggerExit(Collider other)
{
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onExitText);
}
}
方法的范圍
歸因方法不限于文本,例如您可以定義enum
一個通用的碰撞器型別,以允許玩家對不同的位置做出不同的反應,甚至可以定義一般的溫度。
public enum Type
{
None,
Hot,
Cold,
}
public Type type = Type.Hot;
下面是一個這樣的結構示例,它不是定義名稱和標簽,而是如何定義與屬性相關的所有內容,考慮永遠不要在對撞機資訊中輸入玩家旋轉代碼,下面從面向物件編程的角度來看,這個屬性屬于玩家.
if (other.TryGetComponent(out ColliderInfo info))
{
Debug.Log(info.onEnterText);
switch (info.type)
{
case ColliderInfo.Type.Hot:
Reposition();
inHotArea = true; // deal damage until staying in hot area
MeshRenderer.material.color = Color.red;
break;
case ColliderInfo.Type.Cold:
inColdArea = true; // slow effect like decreasing movement speed
MeshRenderer.material.color = Color.cyan;
break;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488289.html
下一篇:檢查兩個游戲物件中的數字作為字串