Files
Fishing2/Assets/ThirdParty/Rewired/Examples/DualShock4SpecialFeatures/Scripts/DualShock4SpecialFeaturesExample.cs
2025-05-10 18:06:44 +08:00

285 lines
10 KiB
C#

// Copyright (c) 2018 Augie R. Maddox, Guavaman Enterprises. All rights reserved.
#region Defines
#if UNITY_2020 || UNITY_2021 || UNITY_2022 || UNITY_2023 || UNITY_6000 || UNITY_6000_0_OR_NEWER
#define UNITY_2020_PLUS
#endif
#if UNITY_2019 || UNITY_2020_PLUS
#define UNITY_2019_PLUS
#endif
#if UNITY_2018 || UNITY_2019_PLUS
#define UNITY_2018_PLUS
#endif
#if UNITY_2017 || UNITY_2018_PLUS
#define UNITY_2017_PLUS
#endif
#if UNITY_5 || UNITY_2017_PLUS
#define UNITY_5_PLUS
#endif
#if UNITY_5_1 || UNITY_5_2 || UNITY_5_3_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_1_PLUS
#endif
#if UNITY_5_2 || UNITY_5_3_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_2_PLUS
#endif
#if UNITY_5_3_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_3_PLUS
#endif
#if UNITY_5_4_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_4_PLUS
#endif
#if UNITY_5_5_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_5_PLUS
#endif
#if UNITY_5_6_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_6_PLUS
#endif
#if UNITY_5_7_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_7_PLUS
#endif
#if UNITY_5_8_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_8_PLUS
#endif
#if UNITY_5_9_OR_NEWER || UNITY_2017_PLUS
#define UNITY_5_9_PLUS
#endif
#pragma warning disable 0219
#pragma warning disable 0618
#pragma warning disable 0649
#pragma warning disable 0067
#endregion
namespace Rewired.Demos {
using UnityEngine;
using System.Collections.Generic;
using Rewired.ControllerExtensions;
[AddComponentMenu("")]
public class DualShock4SpecialFeaturesExample : MonoBehaviour {
private const int maxTouches = 2;
public int playerId = 0;
public Transform touchpadTransform;
public GameObject lightObject;
public Transform accelerometerTransform;
private List<Touch> touches;
private Queue<Touch> unusedTouches;
private bool isFlashing;
private GUIStyle textStyle;
private Player player { get { return ReInput.players.GetPlayer(playerId); } }
private void Awake() {
InitializeTouchObjects();
}
private void Update() {
if (!ReInput.isReady) return;
// Get the first DS4 found assigned to the Player
var ds4 = GetFirstDS4(player);
if(ds4 != null) {
// Set the model's rotation to match the controller's
transform.rotation = ds4.GetOrientation();
// Show touchpad touches
HandleTouchpad(ds4);
// Show accelerometer value
Vector3 accelerometerValue = ds4.GetAccelerometerValue();
accelerometerTransform.LookAt(accelerometerTransform.position + accelerometerValue);
}
if(player.GetButtonDown("CycleLight")) {
SetRandomLightColor();
}
if(player.GetButtonDown("ResetOrientation")) {
ResetOrientation();
}
if(player.GetButtonDown("ToggleLightFlash")) {
if(isFlashing) {
StopLightFlash();
} else {
StartLightFlash();
}
isFlashing = !isFlashing;
}
if (player.GetButtonDown("VibrateLeft")) {
ds4.SetVibration(0, 1f, 1f);
}
if (player.GetButtonDown("VibrateRight")) {
ds4.SetVibration(1, 1f, 1f);
}
}
private void OnGUI() {
if(textStyle == null) {
textStyle = new GUIStyle(GUI.skin.label);
textStyle.fontSize = 20;
textStyle.wordWrap = true;
}
if(GetFirstDS4(player) == null) return; // no DS4 is assigned
GUILayout.BeginArea(new Rect(200f, 100f, Screen.width - 400f, Screen.height - 200f));
GUILayout.Label("Rotate the Dual Shock 4 to see the model rotate in sync.", textStyle);
GUILayout.Label("Touch the touchpad to see them appear on the model.", textStyle);
ActionElementMap aem;
aem = player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "ResetOrientation", true);
if(aem != null) {
GUILayout.Label("Press " + aem.elementIdentifierName + " to reset the orientation. Hold the gamepad facing the screen with sticks pointing up and press the button.", textStyle);
}
aem = player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "CycleLight", true);
if(aem != null) {
GUILayout.Label("Press " + aem.elementIdentifierName + " to change the light color.", textStyle);
}
#if !UNITY_PS4
// Light flash is not supported on the PS4 platform.
aem = player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "ToggleLightFlash", true);
if(aem != null) {
GUILayout.Label("Press " + aem.elementIdentifierName + " to start or stop the light flashing.", textStyle);
}
#endif
aem = player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "VibrateLeft", true);
if (aem != null) {
GUILayout.Label("Press " + aem.elementIdentifierName + " vibrate the left motor.", textStyle);
}
aem = player.controllers.maps.GetFirstElementMapWithAction(ControllerType.Joystick, "VibrateRight", true);
if (aem != null) {
GUILayout.Label("Press " + aem.elementIdentifierName + " vibrate the right motor.", textStyle);
}
GUILayout.EndArea();
}
private void ResetOrientation() {
var ds4 = GetFirstDS4(player);
if(ds4 != null) {
ds4.ResetOrientation();
}
}
private void SetRandomLightColor() {
var ds4 = GetFirstDS4(player);
if(ds4 != null) {
Color color = new Color(
Random.Range(0f, 1f),
Random.Range(0f, 1f),
Random.Range(0f, 1f),
1f
);
ds4.SetLightColor(color);
lightObject.GetComponent<MeshRenderer>().material.color = color;
}
}
private void StartLightFlash() {
// This is not supported on PS4 so get the Standalone DualShock4Extension
DualShock4Extension ds4 = GetFirstDS4(player) as DualShock4Extension;
if(ds4 != null) {
ds4.SetLightFlash(0.5f, 0.5f);
// Light flash is handled by the controller hardware itself and not software.
// The current value cannot be obtained from the controller so it
// cannot be reflected in the 3D model without just recreating the flash to approximate it.
}
}
private void StopLightFlash() {
// This is not supported on PS4 so get the Standalone DualShock4Extension
DualShock4Extension ds4 = GetFirstDS4(player) as DualShock4Extension;
if(ds4 != null) {
ds4.StopLightFlash();
}
}
private IDualShock4Extension GetFirstDS4(Player player) {
foreach(Joystick j in player.controllers.Joysticks) {
// Use the interface because it works for both PS4 and desktop platforms
IDualShock4Extension ds4 = j.GetExtension<IDualShock4Extension>();
if(ds4 == null) continue;
return ds4;
}
return null;
}
private void InitializeTouchObjects() {
touches = new List<Touch>(maxTouches);
unusedTouches = new Queue<Touch>(maxTouches);
// Setup touch objects
for(int i = 0; i < maxTouches; i++) {
Touch touch = new Touch();
// Create spheres to reprensent touches
touch.go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
touch.go.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
#if UNITY_5_PLUS
touch.go.transform.SetParent(touchpadTransform, true);
#else
touch.go.transform.parent = touchpadTransform;
#endif
touch.go.GetComponent<MeshRenderer>().material.color = i == 0 ? Color.red : Color.green;
touch.go.SetActive(false);
unusedTouches.Enqueue(touch);
}
}
private void HandleTouchpad(IDualShock4Extension ds4) {
// Expire old touches first
for(int i = touches.Count - 1; i >= 0; i--) {
Touch touch = touches[i];
if(!ds4.IsTouchingByTouchId(touch.touchId)) { // the touch id is no longer valid
touch.go.SetActive(false); // disable the game object
unusedTouches.Enqueue(touch); // return to the pool
touches.RemoveAt(i); // remove from active touches list
}
}
// Process new touches
for(int i = 0; i < ds4.maxTouches; i++) {
if(!ds4.IsTouching(i)) continue;
int touchId = ds4.GetTouchId(i);
Touch touch = touches.Find(x => x.touchId == touchId); // find the touch with this id
if(touch == null) {
touch = unusedTouches.Dequeue(); // get a new touch from the pool
touches.Add(touch); // add to active touches list
}
touch.touchId = touchId; // store the touch id
touch.go.SetActive(true); // show the object
// Get the touch position
Vector2 position;
ds4.GetTouchPosition(i, out position);
// Set the new position of the touch
touch.go.transform.localPosition = new Vector3(
position.x - 0.5f,
0.5f + (touch.go.transform.localScale.y * 0.5f),
position.y - 0.5f
);
}
}
private class Touch {
public GameObject go;
public int touchId = -1;
}
}
}