π« MUdons 00 - ActiveToggle, ActiveList μΆμν΄λμ€
https://github.com/Mascari4615/MUdons/commit/2763f45666b8930c75c905e4abb8944f262680fe
π² 머리κΈ
μλ VRChat UdonSharpμμλ μΆμ ν΄λμ€/λ©μλλ₯Ό μ§μνμ§ μμλλ°, νΉμ μ λ°μ΄νΈκ° λμλ μΆμ΄ μλν΄λ³΄λ μ»΄νμΌλ μ λκ³ , μ½λ κ·Έλλ‘ λΉλ ν μ€νΈλ₯Ό μ§νν΄λ λ³λ€λ₯Έ λ¬Έμ λ 보μ΄μ§ μμλ€. μΈμ λΆν°μΈκ° μ§μλκ³ μμλ보λ€.
μμμ κΈ°μ‘΄μλ κ°λ₯νκΈ΄ νμ§λ§, μΆμ ν΄λμ€λ₯Ό μ¬μ©ν μ μκ² λ κΉμ, κ·Έλμ κ³ μ³μΌκ² λ€ μκ°νκ³ μλ ObjectActive
, ObjectActiveList
, CanvasGroupActive
, CanvasGroupActiveList
κ·Έλ¦¬κ³ CameraActive
μ°λμ μ½λ/ꡬ쑰 μ€λ³΅λ₯Ό κ°μ νκ³ μ νλ€.
π² λ¬Έμ
λ¨Όμ ~Active
μ°λλ€μ λͺ©μ μ μ 리ν΄λ³Έλ€.
~Active
μ°λλ€μ νΉμ μν©μ νΉμ μμλ₯Ό νμ±ν/λΉνμ±νμν€λ κ°λ¨ν λͺ©μ μ κ°μ§κ³ μλ€.
νΉμ μμμ νμ
μ GameObject
κ° λ μλ μκ³ , CanvasGroup
μ΄ λ μλ μκ³ , Camera
κ° λ μλ μκ³ , λ΄κ° λ§λ MPickup
μ΄ λ μλ μλ€.
μ΄μ¨κ±°λ νμ±ν/λΉνμ±νμ κ°λ
μ κ°μ§ μ μλ κ²μ΄λ©΄ λλ€.
( λ΄κ° λ§λ MPickup
μ μ¬λ¬ ν½μ
κ΄λ ¨ κΈ°λ₯κ³Ό ν¨κ» Enable
κ°λ
μ κ°μ§κ³ μλ€, Enable
μ κ°μ λ°λΌ ν΄λΉ MPickup
μ μ½λΌμ΄λλ λ©μ¬λ λλ¬, μμ μ€λΈμ νΈλ€μ΄ νμ±ν/λΉνμ±νλλ μμ΄λ€. ) ( .. μ΄κ±° μμ ~Active
κΈ°λ₯μ΄μμ? κ·Έλ λ€, MPickup
μ ~Acitve
κΈ°λ₯μ κ°μ§κ³ μμλ€. μΆν MPickup
μ μ΄λ° λΆλΆλ€μ ~Active
μ°λμΌλ‘ λ체ν΄λ μ’μ κ² κ°λ€. )
~Active
μ°λμ μ’
λ₯λ ν¬κ² λ κ°μ§λ‘ λλλ€.
ν κΈκ³Ό 리μ€νΈ.
ν κΈ κΈ°λ₯μ λ§κ·Έλλ‘ μμλ€μ ν κΈ, νμ±ν/λΉνμ±ννλ κΈ°λ₯μ΄κ³ ,
리μ€νΈ κΈ°λ₯μ μ¬λ¬ κ°μ§ μμλ€ μ€μμ, νΉμ μν©μ λ§κ² νΉμ μμλ§μ νμ±νμν€κ³ λλ¨Έμ§λ λΉνμ±νμν€λ, μ‘°κΈμ κΈ°λ₯μ΄ μΆκ°λ μ°λμ΄λ€.
μ΄λ° ν κΈ, 리μ€νΈ κΈ°λ₯λ€μ, λκ°μ μ½λμ νμ
λ§ λ€λ₯Έ μ± ObjectActive
, CanvasGroupActive
, CameraActive
κ°μ΄ μ¬λ¬ μ°λμΌλ‘ μ‘΄μ¬νκ³ μλ€.
μ½λκ° λ§μ΄ μ€λ³΅λκ³ μμκ³ , μ΄λ μλ¦λ΅μ§ μλ€ !
π² μΆμν
λκ°μ μ½λμ νμ
λ§ λ€λ₯΄λ©΄.. μ΄κ±° μΌλ°ν
μμ?
νμ§λ§ μλ°ν λ°μ Έλ³΄λ©΄ λκ°μ μ½λλ μλμλ€.
λμμΌλ‘ νλ νμ
λ€μ κ°λ
μ μΌλ‘λ
λͺ¨λ νμ±ν/λΉνμ±ν μνλ₯Ό κ°μ§κ³ μμ§λ§, μλ‘ λ€λ₯Έ λͺ¨μμΌλ‘ ꡬνλμ΄μκΈ° λλ¬Έμ ( GameObject.active
μ Camera.enabled
λ λ€λ₯΄λ€ ! ) μ΄λ₯Ό μΌλ°ννκΈ°μ λ¬΄λ¦¬κ° μλ€.
λ μ μ΄μ Unity μΈμ€νν°μμ μμλ€μ μ°Έμ‘°λ₯Ό μ§μ λ±λ‘νλ κ²μ΄ μ μ λΌ, νλμ ν΄λμ€/λ©μλμ μ¬λ¬ νμ
μ μν μΌλ°ν λ©μλλ₯Ό λ§λ€ μλ μλ€.
νλμ ν΄λμ€μ GameObject
, CanvasGroup
, Camera
νμ
μ Object
λ‘ λ°μλ΄κ±°λ μ λΆ νλνλ λ³μλ‘ λ§λ€ μλ μμΌλκΉ..
μ»΄ν¬λνΈλ€μ΄λΌλ Behaviour.enable
λ₯Ό μ¨μ μΌλ°νν΄λ³΄λ €κ³ νλλ°, UdonSharpμμλ Behaviour.enabled
μ set
μ μ§μνμ§ μμλ€.
κ·Έλμ ~Active
μ°λλ€μ 곡ν΅λ κ°λ
κ³Ό κΈ°λ₯μ 미리 ꡬνλμ΄ μμ§λ§, νμ±ν/λΉνμ±ν μ²λ¦¬λ μΆμν λ©μλλ‘ λ¨κ²¨λ μΆμν ν΄λμ€λ₯Ό λ§λ€κ³ ,
μ΄λ₯Ό κ° νμ
λ§λ€ μμλ°μ νμ±ν/λΉνμ±ν μνμ λ°λΌ κ° νμ
λ³ μ²λ¦¬λ₯Ό ꡬννλλ‘ νλ€.
π² μ½λ - Core (ActiveToggle
, ActiveList
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public abstract class ActiveToggle : MBase
{
[Header("_" + nameof(ActiveToggle))]
[SerializeField] private bool defaultActive;
[Header("_" + nameof(ActiveToggle) + " - Options")]
[SerializeField] private MBool mBool;
private bool _active;
public bool Active
{
get => _active;
private set
{
_active = value;
UpdateActive();
}
}
private void Start()
{
Init();
}
private void Init()
{
SetActive(defaultActive);
if (mBool != null)
{
mBool.RegisterListener(this, nameof(UpdateValueByMBool));
UpdateValueByMBool();
}
UpdateActive();
}
protected abstract void UpdateActive();
public void SetActive(bool newActive)
{
MDebugLog($"{nameof(SetActive)}({newActive})");
if (mBool != null)
{
mBool.SetValue(newActive);
}
else
{
Active = newActive;
}
}
public void UpdateValueByMBool()
{
if (mBool)
Active = mBool.Value;
}
public void SetMBool(MBool mBool)
{
this.mBool = mBool;
UpdateValueByMBool();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public abstract class ActiveList : MBase
{
[Header("_" + nameof(ActiveList))]
[SerializeField] private int defaultValue;
[Header("_" + nameof(ActiveList) + " - Options")]
[SerializeField] protected MValue mValue;
[SerializeField] protected ActiveListOption option;
[SerializeField] protected int targetIndex = NONE_INT;
private int _value;
public int Value
{
get => _value;
private set
{
_value = value;
UpdateActive();
}
}
private void Start()
{
Init();
}
private void Init()
{
SetValue(defaultValue);
if (mValue != null)
{
InitMValueMinMax();
mValue.RegisterListener(this, nameof(UpdateActiveByMValue));
}
UpdateActive();
}
/// <summary>
/// λμμ΄ λλ μμλ€μ μλ₯Ό λ°νμΌλ‘ mValue.SetMinMaxValue
/// </summary>
protected abstract void InitMValueMinMax();
/// <summary>
/// ActiveListOptionμ λνμ¬ κ° μΌμ΄μ€ λ³λ‘ ꡬν
/// </summary>
/// <param name="value"></param>
protected abstract void UpdateActive();
public void SetValue(int newValue)
{
MDebugLog($"{nameof(SetValue)}({newValue})");
if (mValue != null)
{
mValue.SetValue(newValue);
}
else
{
Value = newValue;
}
}
public void UpdateActiveByMValue()
{
if (mValue)
Value = mValue.Value;
}
public void SetMValue(MValue mValue)
{
this.mValue = mValue;
InitMValueMinMax();
UpdateActiveByMValue();
}
}
π² μ½λ - Impl (ObjectActive
, ObjectActiveList
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ObjectActive : ActiveToggle
{
[Header("_" + nameof(ObjectActive))]
[SerializeField] private GameObject[] activeObjects;
[SerializeField] private GameObject[] disableObjects;
protected override void UpdateActive()
{
MDebugLog($"{nameof(UpdateActive)}");
foreach (GameObject o in activeObjects)
o.SetActive(Active);
foreach (GameObject o in disableObjects)
o.SetActive(!Active);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class ObjectActiveList : ActiveList
{
[Header("_" + nameof(ObjectActiveList))]
[SerializeField] private GameObject[] objectList;
// [SerializeField] private Behaviour[] behaviours; // 240819 : U#μμ .enabled setμ μ§μνμ§ μμ
protected override void InitMValueMinMax()
{
int maxLen = Mathf.Max(objectList.Length);
mValue.SetMinMaxValue(0, maxLen);
}
protected override void UpdateActive()
{
MDebugLog($"{nameof(UpdateActive)}({Value})");
switch (option)
{
// MValueλ₯Ό 리μ€νΈμ μΈλ±μ€λ‘ μ¬μ©ν λ
// μλ₯Ό λ€μ΄, MValueκ° 0μΌ λ 리μ€νΈμ 0λ²μ§Έ μ€λΈμ νΈλ§ νμ±ν, λλ¨Έμ§λ λΉνμ±ν
case ActiveListOption.UseMValueAsListIndex:
for (int i = 0; i < objectList.Length; i++)
{
if (objectList[i])
objectList[i].SetActive(i == Value);
}
break;
// MValueλ₯Ό νκ² μΈλ±μ€λ‘ μ¬μ©ν λ
// μλ₯Ό λ€μ΄, MValueκ° 0μΌ λ νκ² μΈλ±μ€κ° 0μ΄λ©΄ 리μ€νΈμ λͺ¨λ μ€λΈμ νΈ νμ±ν, μλλ©΄ λΉνμ±ν
case ActiveListOption.UseMValueAsTargetIndex:
bool isTargetIndex = Value == targetIndex;
foreach (GameObject obj in objectList)
{
if (obj)
obj.SetActive(isTargetIndex);
}
break;
default:
MDebugLog($"{nameof(UpdateActive)}({Value}) - {option}, Invalid Option");
break;
}
}
}
π² λ§κΌ¬λ¦¬
ObjectActiveList
μ κ²½μ°, νλ‘μ νΈλ₯Ό μ§νν¨μ λ°λΌ GameObject
λΏλ§ μλλΌ CanvasGroup
κ³Ό MPickup
λ ν¨κ» λ€λ£¨κ² λμλλ°, μ΄λ²μ ꡬ쑰λ₯Ό λ°κΎΈλ©΄μ GameObject
λ§ λ€λ£¨λλ‘ μμ νλ€.
CanvasGroup
μ λ³λμ CanvasGroupList
κ° μμΌλ μ΄κ²μΌλ‘ λ체νλ©΄ λκ³ , MPickup
μ λ± ν νλ‘μ νΈμμλ§ μ¬μ©νλ ν°λΌ, λ€μ νμνκ² λλ€λ©΄ CanvasGroupList
μ²λΌ λ³λμ μ°λμ μλ‘ λ§λ€μ΄μΌ ν κ² κ°λ€.
λ¬λμ λ¬λ κ°λ¨ν λͺ©μ μ κ°μ§ μ°λλ€μ΄λΌ, νλ‘μ νΈλ§λ€ κ·Έλκ·Έλ μλ‘ λ§λ€μ΄λ λκΈ΄ νμ§λ§..
μμ£Ό μ°μ΄λ κΈ°λ₯μ κ³μ λ€μ λ§λλ κ² λ³΄λ€λ ν λ² μ λ§λ€μ΄μ μ¬μ¬μ©νλκ² μμ
ν¨μ¨μ΄ μ’λ€κ³ μκ°ν΄μ μ΄λ κ² μμ λͺ¨λλ€μ νλνλ λ§λ€κΈ° μμνλ€.
κ·Έλ°λ° κ·Έλ κ² λ§λ κΈ°λ₯λ€μ λ€μ λ벨λ‘νλ κ³Όμ μμ, μ΄μ νλ‘μ νΈλ€μ μ°λ μνλ€λ ν¨κ» μ μ§λ³΄μνκ² λλλ°, μ΄λ¬λ κ·Έλκ·Έλ λκ°μ κΈ°λ₯μ μλ‘ λ§λλ κ² λ³΄λ€ λ λ§μ μκ°μ΄ μ°κ² λλ κ² κ°κΈ°λ νλ€.
보ν΅μ λΌμ΄λΈλ¬λ¦¬λ€μ²λΌ κ΅¬μ‘°κ° μμ νλμ΄, λ€λ₯Έ μ¬λλ€λ ꡬ쑰λ³κ²½ κ±±μ μμ΄ νΈν μΈ μ μκ³ , λλ μ κΈ°λ₯ κ°λ°μ λμ± μ κ²½μΈ μ μμΌλ©΄ μ’κ² λ€.
v1.0.0
μ ν₯ν΄.