Skip to content

Commit c11b7b8

Browse files
authored
Hd/redo fix inputregistering domainreload (#4358)
* Update InputRegistering.cs * Remove asset modification if InputSystem package is in use * Prevent missuse of InputRegistering while InputSystem package is in use * cleaning * more cleaning * Update code to use Next instead of GetArrayElementAtIndex * Fix strange out of range error
1 parent 1dcd42c commit c11b7b8

File tree

2 files changed

+120
-40
lines changed

2 files changed

+120
-40
lines changed

com.unity.render-pipelines.core/Runtime/Debugging/DebugManager.Actions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ internal bool GetActionToggleDebugMenuWithTouch()
275275

276276
void RegisterInputs()
277277
{
278-
#if UNITY_EDITOR
278+
#if UNITY_EDITOR && !USE_INPUT_SYSTEM
279279
var inputEntries = new List<InputManagerEntry>
280280
{
281281
new InputManagerEntry { name = kEnableDebugBtn1, kind = InputManagerEntry.Kind.KeyOrButton, btnPositive = "left ctrl", altBtnPositive = "joystick button 8" },

com.unity.render-pipelines.core/Runtime/Inputs/InputRegistering.cs

Lines changed: 119 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,36 @@ public enum Kind { KeyOrButton, Mouse, Axis }
1111
public enum Axis { X, Y, Third, Fourth, Fifth, Sixth, Seventh, Eigth }
1212
public enum Joy { All, First, Second }
1313

14-
public string name = "";
15-
public string desc = "";
16-
public string btnNegative = "";
17-
public string btnPositive = "";
18-
public string altBtnNegative = "";
19-
public string altBtnPositive = "";
20-
public float gravity = 0.0f;
21-
public float deadZone = 0.0f;
22-
public float sensitivity = 0.0f;
23-
public bool snap = false;
24-
public bool invert = false;
25-
public Kind kind = Kind.Axis;
26-
public Axis axis = Axis.X;
27-
public Joy joystick = Joy.All;
14+
public string name = "";
15+
public string desc = "";
16+
public string btnNegative = "";
17+
public string btnPositive = "";
18+
public string altBtnNegative = "";
19+
public string altBtnPositive = "";
20+
public float gravity = 0.0f;
21+
public float deadZone = 0.0f;
22+
public float sensitivity = 0.0f;
23+
public bool snap = false;
24+
public bool invert = false;
25+
public Kind kind = Kind.Axis;
26+
public Axis axis = Axis.X;
27+
public Joy joystick = Joy.All;
28+
29+
internal bool IsEqual((string name, InputManagerEntry.Kind kind) partialEntry)
30+
=> this.name == partialEntry.name && this.kind == partialEntry.kind;
31+
32+
internal bool IsEqual(InputManagerEntry other)
33+
=> this.name == other.name && this.kind == other.kind;
2834
}
2935

30-
public class InputRegistering
36+
public static class InputRegistering
3137
{
32-
static bool InputAlreadyRegistered(string name, InputManagerEntry.Kind kind, SerializedProperty spAxes)
33-
{
34-
for (var i = 0; i < spAxes.arraySize; ++i)
35-
{
36-
var spAxis = spAxes.GetArrayElementAtIndex(i);
37-
var axisName = spAxis.FindPropertyRelative("m_Name").stringValue;
38-
var kindValue = spAxis.FindPropertyRelative("type").intValue;
39-
if (axisName == name && (int)kind == kindValue)
40-
return true;
41-
}
38+
static List<InputManagerEntry> s_PendingInputsToRegister = new List<InputManagerEntry>();
4239

43-
return false;
44-
}
40+
static bool havePendingOperation => s_PendingInputsToRegister.Count > 0;
4541

46-
static void WriteEntry(SerializedProperty spAxes, InputManagerEntry entry)
42+
static void CopyEntry(SerializedProperty spAxis, InputManagerEntry entry)
4743
{
48-
if (InputAlreadyRegistered(entry.name, entry.kind, spAxes))
49-
return;
50-
51-
spAxes.InsertArrayElementAtIndex(spAxes.arraySize);
52-
var spAxis = spAxes.GetArrayElementAtIndex(spAxes.arraySize - 1);
5344
spAxis.FindPropertyRelative("m_Name").stringValue = entry.name;
5445
spAxis.FindPropertyRelative("descriptiveName").stringValue = entry.desc;
5546
spAxis.FindPropertyRelative("negativeButton").stringValue = entry.btnNegative;
@@ -66,8 +57,76 @@ static void WriteEntry(SerializedProperty spAxes, InputManagerEntry entry)
6657
spAxis.FindPropertyRelative("joyNum").intValue = (int)entry.joystick;
6758
}
6859

69-
public static void RegisterInputs(List<InputManagerEntry> entries)
60+
static void AddEntriesWithoutCheck(SerializedProperty spAxes, List<InputManagerEntry> newEntries)
61+
{
62+
int endOfCurrentInputList = spAxes.arraySize;
63+
spAxes.arraySize = endOfCurrentInputList + newEntries.Count;
64+
65+
SerializedProperty spAxis = spAxes.GetArrayElementAtIndex(endOfCurrentInputList - 1);
66+
spAxis.Next(false);
67+
for (int i = 0; i < newEntries.Count; ++i, spAxis.Next(false))
68+
CopyEntry(spAxis, newEntries[i]);
69+
}
70+
71+
// Get a representation of the already registered inputs
72+
static List<(string name, InputManagerEntry.Kind kind)> GetCachedInputs(SerializedProperty spAxes)
73+
{
74+
int size = spAxes.arraySize;
75+
List<(string name, InputManagerEntry.Kind kind)> result = new List<(string name, InputManagerEntry.Kind kind)>(size);
76+
77+
SerializedProperty spAxis = spAxes.GetArrayElementAtIndex(0);
78+
for (int i = 0; i < size; ++i, spAxis.Next(false))
79+
result.Add((spAxis.FindPropertyRelative("m_Name").stringValue, (InputManagerEntry.Kind)spAxis.FindPropertyRelative("type").intValue));
80+
return result;
81+
}
82+
83+
static void MakeUniquePendingInputsToRegister()
84+
{
85+
for (int pendingIndex = s_PendingInputsToRegister.Count - 1; pendingIndex > 0; --pendingIndex)
86+
{
87+
InputManagerEntry pendingEntry = s_PendingInputsToRegister[pendingIndex];
88+
int checkedIndex = pendingIndex - 1;
89+
for (; checkedIndex > -1 && !pendingEntry.IsEqual(s_PendingInputsToRegister[checkedIndex]); --checkedIndex) ;
90+
91+
if (checkedIndex == -1)
92+
continue;
93+
94+
// There is a duplicate entry in PendingInputesToRegister.
95+
// Debug.LogWarning($"Two entries with same name and kind are tryed to be added at same time. Only first occurence is kept. Name:{pendingEntry.name} Kind:{pendingEntry.kind}");
96+
97+
// Keep only first.
98+
// Counting decreasingly will have no impact on index before pendingIndex. So we can safely remove it.
99+
s_PendingInputsToRegister.RemoveAt(pendingIndex);
100+
}
101+
}
102+
103+
static void RemovePendingInputsToAddThatAreAlreadyRegistered(List<(string name, InputManagerEntry.Kind kind)> cachedEntries, List<InputManagerEntry> newEntries)
104+
{
105+
for (int newIndex = newEntries.Count - 1; newIndex >= 0; --newIndex)
106+
{
107+
var newEntry = newEntries[newIndex];
108+
int checkedIndex = cachedEntries.Count - 1;
109+
for (; checkedIndex > -1 && !newEntry.IsEqual(cachedEntries[checkedIndex]); --checkedIndex) ;
110+
111+
if (checkedIndex == -1)
112+
continue;
113+
114+
// There is a already a cached entry that correspond.
115+
// Debug.LogWarning($"Another entry with same name and kind already exist. Skiping this one. Name:{newEntry.name} Kind:{newEntry.kind}");
116+
117+
// Keep only first.
118+
// Counting decreasingly will have no impact on index before pendingIndex. So we can safely remove it.
119+
s_PendingInputsToRegister.RemoveAt(newIndex);
120+
}
121+
}
122+
123+
static void DelayedRegisterInput()
70124
{
125+
// Exit quickly if nothing more to register
126+
// (case when several different class try to register, only first call will do all)
127+
if (!havePendingOperation)
128+
return;
129+
71130
// Grab reference to input manager
72131
var assets = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset");
73132
// Temporary fix. This happens some time with HDRP init when it's called before asset database is initialized (probably related to package load order).
@@ -76,18 +135,39 @@ public static void RegisterInputs(List<InputManagerEntry> entries)
76135

77136
var inputManager = assets[0];
78137

79-
// Wrap in serialized object
138+
// Wrap in serialized object to access c++ fields
80139
var soInputManager = new SerializedObject(inputManager);
81140
var spAxes = soInputManager.FindProperty("m_Axes");
82141

83-
foreach (InputManagerEntry entry in entries)
84-
{
85-
WriteEntry(spAxes, entry);
86-
}
142+
// At this point, we assume that entries in spAxes are already unique.
143+
144+
// Ensure no double entry are tried to be registered (trim early)
145+
MakeUniquePendingInputsToRegister();
146+
147+
// Cache already existing entries to minimaly use serialization
148+
var cachedEntries = GetCachedInputs(spAxes);
149+
// And trim pending entries regarding already cached ones.
150+
RemovePendingInputsToAddThatAreAlreadyRegistered(cachedEntries, s_PendingInputsToRegister);
151+
152+
// Add now unique entries
153+
AddEntriesWithoutCheck(spAxes, s_PendingInputsToRegister);
87154

88155
// Commit
89156
soInputManager.ApplyModifiedProperties();
90157
}
158+
159+
public static void RegisterInputs(List<InputManagerEntry> entries)
160+
{
161+
#if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
162+
Debug.LogWarning("Trying to add entry in the legacy InputManager but using InputSystem package. Skiping.");
163+
return;
164+
#else
165+
s_PendingInputsToRegister.AddRange(entries);
166+
167+
//delay the call in order to do only one pass event if several different class register inputs
168+
EditorApplication.delayCall += DelayedRegisterInput;
169+
#endif
170+
}
91171
}
92172
#endif
93173
}

0 commit comments

Comments
 (0)