191 lines
6.5 KiB
C#
191 lines
6.5 KiB
C#
using System;
|
|
using RothenburgAR.Common;
|
|
using RothenburgAR.PointOfInterest;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using System.Collections;
|
|
using System.Threading;
|
|
|
|
namespace RothenburgAR.UI
|
|
{
|
|
public class DetailsPanelBehaviour : MonoBehaviour
|
|
{
|
|
public TextMeshProUGUI DetailsText;
|
|
public ScrollRect DetailsTextScrollRect;
|
|
public DetailsModelBehaviour DetailsModel;
|
|
public GameObject IconLoading;
|
|
public GameObject Icon3D;
|
|
|
|
private void Start()
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
public bool HasModel
|
|
{
|
|
get { return _currentDisplayedModelGo != null; }
|
|
}
|
|
|
|
private GameObject _currentDisplayedModelGo;
|
|
|
|
public void SetText(TextElement el)
|
|
{
|
|
SetText(el.GetTextByLanguage(LanguageManager.Instance.CurrentLanguageKey));
|
|
}
|
|
|
|
public void SetText(String el)
|
|
{
|
|
DetailsText.text = el;
|
|
|
|
// Scroll to top
|
|
DetailsTextScrollRect.normalizedPosition = new Vector2(0, 1);
|
|
}
|
|
|
|
public void SetModelFromPoi(PoiData data)
|
|
{
|
|
if (!data.HasModelDescription) return;
|
|
|
|
StartCoroutine("SetModelCoroutine", data);
|
|
}
|
|
|
|
public IEnumerator SetModelCoroutine(PoiData data)
|
|
{
|
|
if (!data.IsModelLoaded)
|
|
{
|
|
StartCoroutine(data.LoadModel());
|
|
|
|
DetailsModel.gameObject.SetActive(true);
|
|
Icon3D.SetActive(true);
|
|
IconLoading.SetActive(true);
|
|
|
|
while (!data.IsModelLoaded)
|
|
{
|
|
// display loading icon or sth idk
|
|
IconLoading.transform.Rotate(new Vector3(0, 0, 1), -3f);
|
|
|
|
yield return new WaitForSecondsRealtime(.01f);
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
SetModel(data.InstantiateModelPrefab());
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// ignore, just do not display an object
|
|
RemoveModel();
|
|
}
|
|
}
|
|
|
|
public void SetModel(GameObject modelGo)
|
|
{
|
|
modelGo.transform.SetParent(UIManager.Instance.UIObjectCamera.transform, false);
|
|
|
|
var meshFilter = modelGo.GetComponentInChildren<MeshFilter>();
|
|
if (meshFilter == null) throw new Exception("No MeshFilter in Object!");
|
|
|
|
var mesh = meshFilter.mesh;
|
|
if (mesh == null) throw new Exception("No Mesh in Model!");
|
|
|
|
//TODO remove when model metadata rotation is no longer a thing
|
|
mesh.RecalculateBounds();
|
|
|
|
var scale = 1f / Mathf.Max(mesh.bounds.size.x, mesh.bounds.size.y, mesh.bounds.size.z);
|
|
modelGo.transform.localScale = new Vector3(scale, scale, scale);
|
|
modelGo.transform.localPosition = mesh.bounds.center * scale + new Vector3(0, 0, 1.8f);
|
|
|
|
_currentDisplayedModelGo = modelGo;
|
|
DetailsModel.CurrentModel = _currentDisplayedModelGo;
|
|
|
|
DetailsModel.gameObject.SetActive(true);
|
|
Icon3D.SetActive(false);
|
|
IconLoading.SetActive(false);
|
|
}
|
|
|
|
public void RemoveModel()
|
|
{
|
|
DetailsModel.gameObject.SetActive(false);
|
|
DetailsModel.CurrentModel = null;
|
|
|
|
if (HasModel)
|
|
{
|
|
Destroy(_currentDisplayedModelGo);
|
|
_currentDisplayedModelGo = null;
|
|
Icon3D.SetActive(false);
|
|
IconLoading.SetActive(false);
|
|
}
|
|
}
|
|
|
|
public void UpdateOpeningAnimation(Vector3 position)
|
|
{
|
|
float duration = .4f;
|
|
var scale = DisplayManager.Instance.GetComponent<RectTransform>().localScale.x;
|
|
Vector3 screenMiddle = new Vector3(Screen.width / scale, Screen.height / scale, 0) * 0.5f;
|
|
|
|
Vector3 startPos = Camera.main.WorldToScreenPoint(position) / scale - screenMiddle;
|
|
Vector3 endPos = -screenMiddle + new Vector3(25, 25, 0);
|
|
|
|
float startScale = 0.05f;
|
|
float endScale = 1;
|
|
|
|
var anim = GetComponent<Animation>();
|
|
var clip = new AnimationClip
|
|
{
|
|
legacy = true,
|
|
name = "DetailsOpen"
|
|
};
|
|
|
|
// inTangent and outTangent are the curve's angles to and from this keyframe in radians.
|
|
// outTangent for all the first keyframe of all curves are set to directly point at the second frame,
|
|
// effectively disabling the easing and making it a linear motion.
|
|
// beware: setters for Keyframe.inTangent and Keyframe.outTangent seem to not work.
|
|
var curvePosX = new AnimationCurve();
|
|
curvePosX.AddKey(new Keyframe(0f, startPos.x, 0f, (endPos.x - startPos.x) / duration));
|
|
curvePosX.AddKey(new Keyframe(duration, endPos.x));
|
|
|
|
var curvePosY = new AnimationCurve();
|
|
curvePosY.AddKey(new Keyframe(0f, startPos.y, 0f, (endPos.y - startPos.y) / duration));
|
|
curvePosY.AddKey(new Keyframe(duration, endPos.y));
|
|
|
|
clip.SetCurve(string.Empty, typeof(Transform), "localPosition.x", curvePosX);
|
|
clip.SetCurve(string.Empty, typeof(Transform), "localPosition.y", curvePosY);
|
|
|
|
var curveScaleX = new AnimationCurve();
|
|
curveScaleX.AddKey(new Keyframe(0f, startScale, 0f, (endScale - startScale) / duration));
|
|
curveScaleX.AddKey(new Keyframe(duration, endScale));
|
|
|
|
var curveScaleY = new AnimationCurve();
|
|
curveScaleY.AddKey(new Keyframe(0f, startScale, 0f, (endScale - startScale) / duration));
|
|
curveScaleY.AddKey(new Keyframe(duration, endScale));
|
|
|
|
clip.SetCurve(string.Empty, typeof(Transform), "localScale.x", curveScaleX);
|
|
clip.SetCurve(string.Empty, typeof(Transform), "localScale.y", curveScaleY);
|
|
|
|
anim.AddClip(clip, clip.name);
|
|
anim.Play(clip.name);
|
|
}
|
|
|
|
public void OnDetailsPanelDrag(BaseEventData data)
|
|
{
|
|
DetailsModel.RotateModelByDrag(data as PointerEventData);
|
|
}
|
|
|
|
public void OnDetailsPanelPointerDown(BaseEventData data)
|
|
{
|
|
DetailsModel.BeginRotateModelByDrag(data as PointerEventData);
|
|
}
|
|
|
|
public void OnDetailsPanelEndDrag(BaseEventData data)
|
|
{
|
|
DetailsModel.EndRotateModelByDrag(data as PointerEventData);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
RemoveModel();
|
|
}
|
|
}
|
|
} |