BITFALL/Assets/Artists/Scripts/Equip/PlacementController.cs

117 lines
3.5 KiB
C#
Raw Normal View History

2023-11-15 23:54:54 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using BITFALL.Placement;
using BITFALL.Player.Movement;
using BITKit;
using BITKit.Entities;
using BITKit.StateMachine;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Interactions;
namespace BITFALL.Player.Equip
{
public interface IPlacementState:IState{}
public sealed class PlacementController : BITEquipBase<IPlacementState>
{
[SerializeField] private Material material;
[SerializeField] private LayerMask layerMask;
2023-12-03 17:35:43 +08:00
2024-04-06 16:33:57 +08:00
[Header(Constant.Header.Input)]
[SerializeField] private InputActionReference craftAction;
[SerializeField] private InputActionReference snapAction;
2023-11-15 23:54:54 +08:00
[Inject] private IEntityMovement _movement;
2024-04-06 16:33:57 +08:00
[Inject] private IPlayerEquipSelector _equipSelector;
2023-11-15 23:54:54 +08:00
private readonly Optional<Location> allowCraft = new();
2024-04-06 16:33:57 +08:00
private ScriptablePlacement ScriptablePlacement=>Item.GetAssetable() as ScriptablePlacement;
private bool _snap;
2023-11-15 23:54:54 +08:00
public override bool IsSupportItem(IBasicItem item)
{
if (item is null) return false;
var assetable = item.GetAssetable();
return assetable is IPlacementObject;
}
2024-04-06 16:33:57 +08:00
public override void Entry()
2023-11-15 23:54:54 +08:00
{
2024-04-06 16:33:57 +08:00
base.Entry();
2023-11-15 23:54:54 +08:00
inputActionGroup.RegisterCallback(craftAction, OnCraft);
2024-04-06 16:33:57 +08:00
inputActionGroup.RegisterCallback(snapAction, OnSnap);
}
private void OnSnap(InputAction.CallbackContext obj)
{
if(obj.interaction is not PressInteraction) return;
_snap = obj.performed;
}
public override void Exit()
{
base.Exit();
inputActionGroup.UnRegisterCallback(craftAction, OnCraft);
inputActionGroup.UnRegisterCallback(snapAction, OnSnap);
2023-11-15 23:54:54 +08:00
}
private void OnCraft(InputAction.CallbackContext obj)
{
if (BITAppForUnity.AllowCursor.Allow) return;
if (obj is not { interaction: PressInteraction, performed: true }) return;
if (!allowCraft.Allow) return;
2024-04-06 16:33:57 +08:00
if (_inventory.Remove(Item))
{
var instance = ScriptablePlacement.Clone() as UnityPlacementObject;
instance!.transform.SetPositionAndRotation(allowCraft.Value, allowCraft.Value);
if (instance.TryGetComponent<IWorldItemObject>(out var worldItemObject))
{
worldItemObject.Item = Item;
}
}
_equipSelector.Cancel();
2023-11-15 23:54:54 +08:00
}
public override void OnUpdate(float deltaTime)
{
var startPosition = Camera.main.transform.position;
var direction = Camera.main.transform.forward;
var distance = 3.2f;
var position = _movement.Position;
var rotation = _movement.Rotation;
// ReSharper disable once AssignmentInConditionalExpression
if (allowCraft.Allow = Physics.Raycast(startPosition, direction, out var hit, distance, layerMask))
{
2024-04-06 16:33:57 +08:00
position = hit.point;
Debug.DrawLine(hit.point, hit.point + hit.normal, Color.magenta);
rotation = _movement.Rotation * Quaternion.Euler(0, 180, 0);
if (_snap)
{
position = hit.point + hit.normal * 0.32f;
position = MathV.AlignToGrid(position, ScriptablePlacement.PositionIncrement);
rotation = MathQ.AlignRotation(rotation, ScriptablePlacement.RotationIncrement);
}
2023-11-15 23:54:54 +08:00
2024-04-06 16:33:57 +08:00
foreach (var x in ScriptablePlacement.Object.As<MonoBehaviour>().GetComponentsInChildren<MeshFilter>())
2023-11-15 23:54:54 +08:00
{
Graphics.DrawMesh(x.sharedMesh,position+rotation*x.transform.localPosition,rotation * x.transform.localRotation,material,LayerMask.NameToLayer("Default"));
}
allowCraft.Value = new Location(position, rotation);
2024-04-06 16:33:57 +08:00
2023-11-15 23:54:54 +08:00
}
else
{
Debug.DrawLine(startPosition, startPosition + direction * distance, Color.red);
}
}
}
}