2017-04-02 42 views
0

所以我用下面的脚本,它使用谷歌的GvrLaserPointerImpl(谷歌白日梦)瞬移围绕我的场景:扩展GvrLaserPointerImpl让光线投射目标信息的谷歌白日梦

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); 
      } 
     } 
    } 
} 

对于我的比赛,我需要知道什么GvrLaserPointerImpl光线正在击中。如果你看一下GvrLaserPointerImpl脚本OnPointerEnter参数可以看到,有一个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) 
} 

我希望延长GvrLaserPointerImpl类并覆盖OnPointerEnter方法公开公开targetObject,这样我可以在我的PlayerTeleport脚本中进行检查,以检查raycast是否正在用标签击中targetObject。我不知道该怎么把overPided OnPointerEnter方法访问targetObject类。 GvrLaserPointerImpl继承自抽象的GvrBasePointer类,因此抽象类中没有任何内容告诉我如何做到这一点。

任何帮助,将不胜感激!

回答

1

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

public class ClickResponder : MonoBehaviour, IPointerClickHandler { 
    public void OnPointerClick(PointerEventData eventData) { 
     Debug.Log("Clicked!"); 
    } 
} 

如果不为你的使用情况,您还可以能够通过这个API来访问当前正指向对象:https://docs.unity3d.com/ScriptReference/EventSystems.EventSystem-currentSelectedGameObject.html

如果没有这些方法,为您的工作需要,你可以像下面这样暴露GvrLaserPointerImpl中的目标对象:

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) 
} 

我希望有帮助!

+0

谢谢我真的很感激它! – fiixed