274 lines
7.2 KiB
C#
274 lines
7.2 KiB
C#
namespace Marro.PacManUdon
|
|
{
|
|
using System;
|
|
using UnityEngine;
|
|
using VRC.SDKBase;
|
|
using VRC.Udon.Common;
|
|
|
|
enum InputMethod
|
|
{
|
|
KeyboardMouse,
|
|
Other,
|
|
}
|
|
|
|
public class PlayerInput : SyncedObject
|
|
{
|
|
public bool active;
|
|
|
|
private GameManager gameManager;
|
|
|
|
private VRCPlayerApi player;
|
|
private InputMethod inputMethod;
|
|
|
|
private Direction resultInput;
|
|
private Vector2 analogInput;
|
|
private bool dirty;
|
|
private HandType lastUsedHand;
|
|
private bool horizontalPriority;
|
|
|
|
public void Initialize(GameManager gameManager)
|
|
{
|
|
this.gameManager = gameManager;
|
|
|
|
player = Networking.LocalPlayer;
|
|
inputMethod = InputMethod.KeyboardMouse;
|
|
|
|
resultInput = Direction.Zero;
|
|
analogInput = Vector2.zero;
|
|
dirty = false;
|
|
horizontalPriority = false;
|
|
|
|
SubscribeToEvent(NetworkEventType.InputChange);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (active)
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.R))
|
|
{
|
|
gameManager.ResetButtonPressed();
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.G))
|
|
{
|
|
gameManager.networkManager.DoFullSync();
|
|
}
|
|
|
|
if (Input.GetKeyDown(KeyCode.C))
|
|
{
|
|
gameManager.JumpToTimeSequenceBoardClear();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.T))
|
|
{
|
|
gameManager.ResetButtonPressed();
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void SyncedUpdate()
|
|
{
|
|
if (dirty) // Update now to ensure input feedback is performed timely
|
|
{
|
|
UpdateResultInput();
|
|
}
|
|
}
|
|
|
|
public void Activate()
|
|
{
|
|
Debug.Log($"{gameObject} got activated, {player} was immobilized");
|
|
active = true;
|
|
player.SetWalkSpeed(0);
|
|
player.SetRunSpeed(0);
|
|
player.SetStrafeSpeed(0);
|
|
|
|
gameManager.JoystickGrabbed();
|
|
}
|
|
|
|
public void Deactivate()
|
|
{
|
|
Debug.Log($"{gameObject} got deactivated, {player} was released");
|
|
player.SetWalkSpeed(2);
|
|
player.SetRunSpeed(4);
|
|
player.SetStrafeSpeed(2);
|
|
active = false;
|
|
|
|
gameManager.JoystickReleased();
|
|
}
|
|
|
|
public override void InputJump(bool pressed, UdonInputEventArgs args)
|
|
{
|
|
if (!active)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (pressed)
|
|
{
|
|
Deactivate();
|
|
}
|
|
}
|
|
|
|
public override void InputMoveHorizontal(float value, UdonInputEventArgs args)
|
|
{
|
|
if (!active)
|
|
{
|
|
return;
|
|
}
|
|
|
|
analogInput.x = value;
|
|
lastUsedHand = args.handType;
|
|
dirty = true;
|
|
}
|
|
|
|
public override void InputMoveVertical(float value, UdonInputEventArgs args)
|
|
{
|
|
if (!active)
|
|
{
|
|
return;
|
|
}
|
|
|
|
analogInput.y = value;
|
|
lastUsedHand = args.handType;
|
|
dirty = true;
|
|
}
|
|
|
|
public override void OnInputMethodChanged(VRCInputMethod inputMethod)
|
|
{
|
|
switch (inputMethod)
|
|
{
|
|
case VRCInputMethod.Keyboard:
|
|
case VRCInputMethod.Mouse:
|
|
this.inputMethod = InputMethod.KeyboardMouse;
|
|
return;
|
|
default:
|
|
this.inputMethod = InputMethod.Other;
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void UpdateResultInput()
|
|
{
|
|
dirty = false;
|
|
var newResult = GetResultInput(analogInput);
|
|
|
|
if (newResult == resultInput)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Debug.Log($"Switched to input direction {newResult} from analogInput {analogInput} with HorizontalPriority {horizontalPriority}");
|
|
|
|
resultInput = newResult;
|
|
networkManager.SendEventSoon(NetworkEventType.InputChange, true);
|
|
PlayHaptics();
|
|
}
|
|
|
|
private void PlayHaptics()
|
|
{
|
|
if (inputMethod == InputMethod.KeyboardMouse)
|
|
{
|
|
return;
|
|
}
|
|
|
|
VRC_Pickup.PickupHand hand;
|
|
switch (lastUsedHand)
|
|
{
|
|
case HandType.LEFT:
|
|
hand = VRC_Pickup.PickupHand.Left;
|
|
break;
|
|
case HandType.RIGHT:
|
|
hand = VRC_Pickup.PickupHand.Right;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
player.PlayHapticEventInHand(hand, 0.1f, 0.15f, 75);
|
|
}
|
|
|
|
private Direction GetResultInput(Vector2 analogInput)
|
|
{
|
|
if (analogInput.magnitude < 0.8)
|
|
{
|
|
return Direction.Zero;
|
|
}
|
|
|
|
var normalized = analogInput.normalized;
|
|
|
|
Debug.Log($"Checking analogInput {analogInput} with HorizontalPriority {horizontalPriority}, normalized {normalized}");
|
|
|
|
const float directionDivider = 0.72f;
|
|
if (normalized.x > directionDivider)
|
|
{
|
|
horizontalPriority = false;
|
|
return Direction.Right;
|
|
}
|
|
else if (normalized.x < -directionDivider)
|
|
{
|
|
horizontalPriority = false;
|
|
return Direction.Left;
|
|
}
|
|
else if (normalized.y > directionDivider)
|
|
{
|
|
horizontalPriority = true;
|
|
return Direction.Up;
|
|
}
|
|
else if (normalized.y < -directionDivider)
|
|
{
|
|
horizontalPriority = true;
|
|
return Direction.Down;
|
|
}
|
|
|
|
if (horizontalPriority)
|
|
{
|
|
if (normalized.x > 0)
|
|
{
|
|
return Direction.Right;
|
|
}
|
|
return Direction.Left;
|
|
}
|
|
|
|
if (normalized.y > 0)
|
|
{
|
|
return Direction.Up;
|
|
}
|
|
return Direction.Down;
|
|
}
|
|
|
|
public Direction GetDirection()
|
|
{
|
|
if (dirty) // Update now to reduce input delay
|
|
{
|
|
UpdateResultInput();
|
|
}
|
|
|
|
return resultInput;
|
|
}
|
|
|
|
public override void CollectSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
if (eventType != NetworkEventType.InputChange)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ByteUtils.AppendAsByte(data, (int)resultInput, ref index);
|
|
}
|
|
|
|
public override bool WriteSyncedData(byte[] data, ref int index, NetworkEventType eventType)
|
|
{
|
|
if (eventType != NetworkEventType.InputChange)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
resultInput = (Direction)ByteUtils.ReadByte(data, ref index);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
} |