C# 扩展gvrlaserpointempl以获取Google Daydream的Raycast目标信息

C# 扩展gvrlaserpointempl以获取Google Daydream的Raycast目标信息,c#,unity3d,google-vr,C#,Unity3d,Google Vr,因此,我使用下面的脚本,它使用谷歌的gvrlaserpointempl(谷歌白日梦)来传送我的场景: public class PlayerTeleport : MonoBehaviour { void Update() { if (GvrController.AppButtonUp) { GvrLaserPointerImpl laserPointerImpl = (GvrLaserPointerImpl)GvrPointerManager.P

因此,我使用下面的脚本,它使用谷歌的gvrlaserpointempl(谷歌白日梦)来传送我的场景:

public class PlayerTeleport : MonoBehaviour {

    void Update() {
        if (GvrController.AppButtonUp) {
            GvrLaserPointerImpl laserPointerImpl = (GvrLaserPointerImpl)GvrPointerManager.Pointer;
            if (laserPointerImpl.IsPointerIntersecting) {
                transform.position = new Vector3(laserPointerImpl.PointerIntersection.x, transform.position.y, laserPointerImpl.PointerIntersection.z);
            }
        }
    }
}
对于我的游戏,我需要知道GVRLASERPORINTERIMPL光线投射击中了什么。如果查看指针引用器参数上的gvrlaserpointempl脚本,可以看到存在一个targetObject,但它没有以任何方式公开或处理:

/// Implementation of GvrBasePointer for a laser pointer visual.
/// This script should be attached to the controller object.
/// The laser visual is important to help users locate their cursor
/// when its not directly in their field of view.
public class GvrLaserPointerImpl : GvrBasePointer {
  /// Small offset to prevent z-fighting of the reticle (meters).
  private const float Z_OFFSET_EPSILON = 0.1f;

  /// Size of the reticle in meters as seen from 1 meter.
  private const float RETICLE_SIZE = 0.01f;

  public Camera MainCamera { private get; set; }

  public Color LaserColor { private get; set; }

  public LineRenderer LaserLineRenderer { get; set; }

  public GameObject Reticle { get; set; }

  public float MaxLaserDistance { private get; set; }

  public float MaxReticleDistance { private get; set; }

  // Properties exposed for testing purposes.
  public Vector3 PointerIntersection { get; private set; }

  public bool IsPointerIntersecting { get; private set; }

  public Ray PointerIntersectionRay { get; private set; }

  public override float MaxPointerDistance {
    get {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
      return MaxReticleDistance;
#else
      return 0;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    }
  }

  public GvrLaserPointerImpl() {
    MaxLaserDistance = 0.75f;
    MaxReticleDistance = 2.5f;
  }

#if !(UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR))
  public override void OnStart() {
    // Don't call base.Start() so that this pointer isn't activated when
    // the editor doesn't have UNITY_HAS_GOOGLE_VR.
  }
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)

  public override void OnInputModuleEnabled() {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    if (LaserLineRenderer != null) {
      LaserLineRenderer.enabled = true;
    }
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

  public override void OnInputModuleDisabled() {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    if (LaserLineRenderer != null) {
      LaserLineRenderer.enabled = false;
    }
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

  public override void OnPointerEnter(GameObject targetObject, Vector3 intersectionPosition,
      Ray intersectionRay, bool isInteractive) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    PointerIntersection = intersectionPosition;
    PointerIntersectionRay = intersectionRay;
    IsPointerIntersecting = true;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

  public override void OnPointerHover(GameObject targetObject, Vector3 intersectionPosition,
      Ray intersectionRay, bool isInteractive) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    PointerIntersection = intersectionPosition;
    PointerIntersectionRay = intersectionRay;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

  public override void OnPointerExit(GameObject targetObject) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    PointerIntersection = Vector3.zero;
    PointerIntersectionRay = new Ray();
    IsPointerIntersecting = false;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

  public override void OnPointerClickDown() {
    // User has performed a click on the target.  In a derived class, you could
    // handle visual feedback such as laser or cursor color changes here.
  }

  public override void OnPointerClickUp() {
    // User has released a click from the target.  In a derived class, you could
    // handle visual feedback such as laser or cursor color changes here.
  }

  public override void GetPointerRadius(out float enterRadius, out float exitRadius) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    if (Reticle != null) {
      float reticleScale = Reticle.transform.localScale.x;

      // Fixed size for enter radius to avoid flickering.
      // This will cause some slight variability based on the distance of the object
      // from the camera, and is optimized for the average case.
      enterRadius = RETICLE_SIZE * 0.5f;

      // Dynamic size for exit radius.
      // Always correct because we know the intersection point of the object and can
      // therefore use the correct radius based on the object's distance from the camera.
      exitRadius = reticleScale;
    } else {
      enterRadius = 0.0f;
      exitRadius = 0.0f;
    }
#else
    enterRadius = 0.0f;
    exitRadius = 0.0f;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  }

#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
  public void OnUpdate() {
    // Set the reticle's position and scale
    if (Reticle != null) {
      if (IsPointerIntersecting) {
        Vector3 difference = PointerIntersection - PointerIntersectionRay.origin;
        Vector3 clampedDifference = Vector3.ClampMagnitude(difference, MaxReticleDistance);
        Vector3 clampedPosition = PointerIntersectionRay.origin + clampedDifference;
        Reticle.transform.position = clampedPosition;
      } else {
        Reticle.transform.localPosition = new Vector3(0, 0, MaxReticleDistance);
      }

      float reticleDistanceFromCamera =
        (Reticle.transform.position - MainCamera.transform.position).magnitude;
      float scale = RETICLE_SIZE * reticleDistanceFromCamera;
      Reticle.transform.localScale = new Vector3(scale, scale, scale);
    }

    if (LaserLineRenderer == null) {
      Debug.LogWarning("Line renderer is null, returning");
      return;
    }

    // Set the line renderer positions.
    Vector3 lineEndPoint;
    if (IsPointerIntersecting) {
      Vector3 laserDiff = PointerIntersection - base.PointerTransform.position;
      float intersectionDistance = laserDiff.magnitude;
      Vector3 direction = laserDiff.normalized;
      float laserDistance = intersectionDistance > MaxLaserDistance ? MaxLaserDistance : intersectionDistance;
      lineEndPoint = base.PointerTransform.position + (direction * laserDistance);
    } else {
      lineEndPoint = base.PointerTransform.position + (base.PointerTransform.forward * MaxLaserDistance);
    }
    LaserLineRenderer.SetPositions(new Vector3[] {base.PointerTransform.position, lineEndPoint});

    // Adjust transparency
    float alpha = GvrControllerVisual.AlphaValue;
    LaserLineRenderer.SetColors(Color.Lerp(Color.clear, LaserColor, alpha), Color.clear);
  }


#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
}
我想扩展gvrlaserpointempl类并重写OnPointerEnter方法来公开targetObject,这样我就可以在PlayerTeleport脚本中进行检查,查看光线投射是否使用标记击中targetObject。不过,我不确定在重写的OnPointerEnter方法中放入什么来访问targetObject类。gvrlaserpointempl继承自抽象的GvrBasePointer类,因此抽象类中没有任何内容可以告诉我如何做到这一点


任何帮助都将不胜感激

使用Unity的事件系统进行交互时,典型的设计模式是在实现IEventSystemHandler的目标对象上放置一个脚本。例如:

public class ClickResponder : MonoBehaviour, IPointerClickHandler {
    public void OnPointerClick(PointerEventData eventData) {
        Debug.Log("Clicked!");
    }
}
如果这不适用于您的用例,您还可以通过以下API访问当前指向的对象:

如果这两种方法都不能满足您的需要,您可以在gvrlaserpointempl中公开目标对象,如下所示:

public GameObject TargetObject { get; private set; }

public override void OnPointerEnter(GameObject targetObject, Vector3 intersectionPosition,
  Ray intersectionRay, bool isInteractive) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    TargetObject = targetObject;
    PointerIntersection = intersectionPosition;
    PointerIntersectionRay = intersectionRay;
IsPointerIntersecting = true;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
}

public override void OnPointerExit(GameObject targetObject) {
#if UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
    TargetObject = null;
    PointerIntersection = Vector3.zero;
    PointerIntersectionRay = new Ray();
    IsPointerIntersecting = false;
#endif  // UNITY_HAS_GOOGLEVR && (UNITY_ANDROID || UNITY_EDITOR)
}
我希望这有帮助