2017-04-02 35 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