133 lines
3 KiB
C#
133 lines
3 KiB
C#
using System;
|
|
using KitsuneCafe.ItemSystem;
|
|
using KitsuneCafe.SOAP;
|
|
using KitsuneCafe.Sys;
|
|
using R3;
|
|
using UnityEngine;
|
|
using Wacs.Core.Instructions;
|
|
|
|
namespace KitsuneCafe.UI
|
|
{
|
|
public class ItemPreview : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
private ItemValue selectedItem;
|
|
|
|
[SerializeField]
|
|
private new Transform camera;
|
|
|
|
[Header("Rotation")]
|
|
[SerializeField]
|
|
private Vector2Value rotationDelta;
|
|
|
|
[SerializeField]
|
|
private float sensitivity = 20;
|
|
|
|
[SerializeField]
|
|
private float angleSnap = 10;
|
|
|
|
[Header("Zoom")]
|
|
[SerializeField]
|
|
private FloatValue zoom;
|
|
|
|
[SerializeField]
|
|
private float zoomSensitivity = 0.5f;
|
|
|
|
private Vector3 initialPosition;
|
|
|
|
[SerializeField]
|
|
private Layer previewLayer;
|
|
|
|
private GameObject instance;
|
|
|
|
private void Start()
|
|
{
|
|
if (selectedItem.Value != null)
|
|
{
|
|
ChangeItemPreview(selectedItem.Value);
|
|
}
|
|
|
|
var d = Disposable.CreateBuilder();
|
|
|
|
selectedItem.AsObservable()
|
|
.Subscribe(ChangeItemPreview)
|
|
.AddTo(ref d);
|
|
|
|
rotationDelta.AsObservable()
|
|
.Where(_ => instance != null)
|
|
.Subscribe(RotatePreview)
|
|
.AddTo(ref d);
|
|
|
|
zoom.AsObservable()
|
|
.Where(_ => instance != null)
|
|
.Subscribe(ZoomPreview)
|
|
.AddTo(ref d);
|
|
|
|
d.RegisterTo(destroyCancellationToken);
|
|
}
|
|
|
|
private void ZoomPreview(float amount)
|
|
{
|
|
if (instance == null) { return; }
|
|
|
|
var position = initialPosition;
|
|
position.z += amount * zoomSensitivity;
|
|
instance.transform.position = position;
|
|
}
|
|
|
|
private void ChangeItemPreview(Item item)
|
|
{
|
|
if (instance != null)
|
|
{
|
|
Destroy(instance);
|
|
instance = null;
|
|
}
|
|
|
|
if (item != null)
|
|
{
|
|
instance = item.CreatePreview();
|
|
instance.layer = previewLayer;
|
|
instance.transform.SetParent(transform);
|
|
initialPosition = instance.transform.position;
|
|
|
|
ResetPreviewValues();
|
|
}
|
|
}
|
|
|
|
private void ResetPreviewValues()
|
|
{
|
|
zoom.Value = 0;
|
|
rotationDelta.Value = Vector2.zero;
|
|
}
|
|
|
|
public void RotatePreview(Vector2 delta)
|
|
{
|
|
if (instance == null || camera == null) { return; }
|
|
|
|
var yawAngle = -delta.x * sensitivity * Time.deltaTime;
|
|
var yawRotation = Quaternion.AngleAxis(yawAngle, camera.up);
|
|
var pitchAngle = -delta.y * sensitivity * Time.deltaTime;
|
|
|
|
var pitchRotation = Quaternion.AngleAxis(pitchAngle, camera.right);
|
|
var combinedRotation = pitchRotation * yawRotation;
|
|
instance.transform.rotation = combinedRotation * instance.transform.rotation;
|
|
|
|
ApplyAngleSnapping();
|
|
}
|
|
|
|
public void ApplyAngleSnapping()
|
|
{
|
|
if (instance == null) return;
|
|
|
|
Vector3 euler = instance.transform.rotation.eulerAngles;
|
|
|
|
Quaternion rotation = Quaternion.Euler(
|
|
Mathf.Round(euler.x / angleSnap) * angleSnap,
|
|
Mathf.Round(euler.y / angleSnap) * angleSnap,
|
|
Mathf.Round(euler.z / angleSnap) * angleSnap
|
|
);
|
|
|
|
instance.transform.rotation = rotation;
|
|
}
|
|
}
|
|
}
|