【问题标题】:Raycast not detected when it should应在何时未检测到 Raycast
【发布时间】:2014-12-28 02:29:57
【问题描述】:

谁能告诉我代码有什么问题? 如果你能看到,只要玩家在光线投射的范围内。敌人变成红色。 但出于某种原因。即使玩家已经满足了让敌人变红的要求。它变回白色。这仅在您手动移动时可见,在正常速度下它看起来好像在闪烁。

我认为发生这种情况的原因是,其中一个光线投射不再满足要求。大概与此有关。我不知道确切。所以请帮我解决这个问题。

提前致谢。

这张图显示,即使玩家在使敌人变红的要求范围内。它没有。为什么?

using UnityEngine;
using System.Collections;

/* TL = Top Left
 * TR = Top Right
 * BL = Bottom Left
 * BR = Bottom Right
 */

public class Script_v2 : MonoBehaviour {

    // Player Properties
    private GameObject player;
    public Vector3 playerSize;
    private Vector3 playerTransform;
    public Vector3 playerTransformTL;
    public Vector3 playerTransformTR;
    public Vector3 playerTransformBL;
    public Vector3 playerTransformBR;

    private Vector3 newPlayerTransformTL;
    private Vector3 newPlayerTransformTR;

    private Vector3[] playerRaycastPoints;


    // Enemy Properties
    private Vector3 enemyTransformTL;
    private Vector3 enemyTransformTR;
    private Vector3 enemyTransformBL;
    private Vector3 enemyTransformBR;

    public float distance;
    public Vector3 enemySize;

    // Detection Alerts
    public bool alerted;
    public bool alertedLock;
    public bool dead;

    Ray ray;
    RaycastHit hit;

    // Use this for initialization
    void Start () {
        playerRaycastPoints = new Vector3[4];

        distance = 3f;
        player = GameObject.FindGameObjectWithTag ("Player");


    }

    // Update is called once per frame
    void Update () {

        enemyTransformTL = new Vector3 (transform.position.x - 0.5f, transform.position.y + 0.5f, transform.position.z);
        enemyTransformTR = new Vector3 (transform.position.x + 0.5f, transform.position.y + 0.5f, transform.position.z);


        enemyTransform_TL_TR ();
        detectionAlert ();
        Reference_Player_Transform_Points ();
        Player_Transform_Points_Detection ();



    }

    void OnDrawGizmos() {
        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere (new Vector3(transform.position.x - 0.5f, transform.position.y + 0.5f, transform.position.z), distance);
        Gizmos.DrawWireSphere (new Vector3(transform.position.x + 0.5f, transform.position.y + 0.5f, transform.position.z), distance);
    }

    public void enemyTransform_TL_TR() {

        for (int i = 0; i < 4; i++) {

            double enemyAngleTL = Mathf.Atan2(playerRaycastPoints[i].y - ( transform.position.y + 0.5f ),
                                              playerRaycastPoints[i].x - ( transform.position.x - 0.5f )) * 180f / 3.14159265f;
            Debug.Log (enemyAngleTL);
            double enemyAngleTR = Mathf.Atan2 (playerRaycastPoints[i].y - (transform.position.y + 0.5f),
                                               playerRaycastPoints[i].x - (transform.position.x + 0.5f)) * 180f / 3.14159265f;

            Vector3 directionTL = (playerRaycastPoints[i] - enemyTransformTL).normalized;
            Ray rayTL = new Ray(enemyTransformTL, directionTL);
            RaycastHit hitTL;
            Vector3 directionTR = (playerRaycastPoints[i] - enemyTransformTR).normalized;
            Ray rayTR = new Ray (enemyTransformTR, directionTR);
            RaycastHit hitTR;


            //Debug.DrawRay (rayTR.origin, rayTR.direction * distance, Color.yellow);

            if(Physics.Raycast (rayTL, out hitTL, distance)) {
                if((enemyAngleTL > 90 && enemyAngleTL < 180)) {
                    Debug.DrawRay (rayTL.origin, rayTL.direction * distance, Color.yellow);
                    alerted = true;

                }

            }
            else {
                alerted = false;
            }


        }


    }

    public void detectionAlert() {
        if (alerted == true) {
            gameObject.renderer.material.color = Color.red;     
        }
        else {
            gameObject.renderer.material.color = Color.white;
        }
    }

    private void Reference_Player_Transform_Points() {

        playerSize = player.transform.localScale;

        playerTransformTL = new Vector3(player.transform.position.x - (playerSize.x / 2),
                                        player.transform.position.y + playerSize.y  / 2,
                                        player.transform.position.z);
        playerTransformTR = new Vector3(player.transform.position.x + (playerSize.x / 2),
                                        player.transform.position.y + playerSize.y  / 2,
                                        player.transform.position.z);
        playerTransformBL = new Vector3(player.transform.position.x - (playerSize.x / 2),
                                        player.transform.position.y - playerSize.y  / 2,
                                        player.transform.position.z);
        playerTransformBR = new Vector3(player.transform.position.x + (playerSize.x / 2),
                                        player.transform.position.y - playerSize.y  / 2,
                                        player.transform.position.z);

        playerRaycastPoints [0] = playerTransformTL;
        playerRaycastPoints [1] = playerTransformTR;
        playerRaycastPoints [2] = playerTransformBL;
        playerRaycastPoints [3] = playerTransformBR;

    }



}

【问题讨论】:

  • 您的部分脚本丢失,即 Player_Transform_Points_Detection() 方法...

标签: c# vector unity3d detection raycasting


【解决方案1】:

我没有仔细阅读整本书,但我闻到了一些可疑的味道,这里是:你的状态(颜色)取决于“警报”布尔值,它只在enemyTransform_TL_TR() 中受到影响。

您正在通过播放器框的 4 个顶点进行投射(在 2D 中,对吗?),在 for 循环中(这是有味道的部分)。

因此,如果一次施法成功,它将开启警报,但如果 for 中的下一次施法失败,那么它将关闭警报。也许你应该在 for 循环之前关闭 alert,然后在第一次成功转换时打开它并中断 for?

另外,我不喜欢那个演员的样子,你没有处理其中一种情况(见我的“其他”评论):

   if (Physics.Raycast(rayTL, out hitTL, distance))
   {
      if ((enemyAngleTL > 90 && enemyAngleTL < 180))
      {
         Debug.DrawRay(rayTL.origin, rayTL.direction * distance, Color.yellow);
         alerted = true;
      }
      // else: what then? should alerted be false? here's you're just leaving it as is...
   }
   else
   {
      alerted = false;
   }

除此之外,正如我在评论中所说,您的脚本没有开箱即用地编译,缺少方法 Player_Transform_Points_Detection()

而且,您的代码可以进行一些清理:大量未使用的变量、方法和变量因不明原因而公开。

您应该缓存更多内容:就像在Reference_Player_Transform_Points() 中一样,您正在执行player.transform.position 12 次!每次都有效地从引擎中拉出位置。只需拉一次var playerPos = player.transform.position;,然后在任何地方使用playerPos。到处都是playerRaycastPoints[i]。您的代码将更快且更具可读性。

您还将 playerSize 除以 2 4 次,您可以执行一次(然后乘以 0.5f,因为除法成本很高,但是这种挑剔,编译器可能会为您执行此操作,我'我不确定)。

您可以使用Mathf.Rad2Deg 代替180f / 3.14159265f,或者至少使用Mathf.PI

您可以直接内联初始化字段:private Vector3[] playerRaycastPoints = new Vector3[4];,而不是在 Start() 上进行初始化。

...好吧,我现在就停下来;)!

【讨论】:

  • 谢谢你!我真的很欣赏你说的。非常感谢 !哈哈,但是嗯,我解决了这个放置问题,alerted = true;在 for 循环之外。至于缺少的功能。我忘了在更新中删除它,因为我删除了整个功能,因为它不再需要了。如果可以的话,请帮助我:gamedev.stackexchange.com/questions/90368/…
  • 没问题。如果有帮助,请不要忘记接受答案。我明天看看能不能再看看另一个问题。
猜你喜欢
  • 2020-11-14
  • 1970-01-01
  • 2017-07-14
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
相关资源
最近更新 更多