46 public GameObject Target {
48 if (transform.childCount > 0)
50 return transform.GetChild(0).gameObject;
56 [Header(
"Idle & Activation settings")]
60 protected float autoActivateRadius = 0.05f;
62 protected float removeRadius = 0.25f;
64 protected float restorePosSpeed = 1f;
66 protected float activeTimeout = 0.5f;
68 protected AnimationCurve restoreCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
70 [Header(
"Duplication settings")]
72 private bool limitDuplicates =
false;
74 protected int maxDuplicates = 10;
76 protected float duplicateSpeed = 0.5f;
78 protected AnimationCurve duplicateGrowCurve = AnimationCurve.EaseInOut(0f, 0.001f, 1f, 1f);
80 [Header(
"Current state")]
90 StartCoroutine(UpdateTarget());
95 Debug.LogError(
"No target found in duplicator.");
99 targetScale = Target.transform.localScale;
100 targetPos = Target.transform.localPosition;
101 targetRot = Target.transform.localRotation;
105 normalizedTime = restoreCurve.Evaluate(normalizedTime);
106 Target.transform.localPosition = Vector3.Lerp(Target.transform.localPosition, targetPos, normalizedTime);
107 Target.transform.localRotation = Quaternion.Lerp(Target.transform.localRotation, targetRot, normalizedTime);
112 while (Target == null) {
120 float normalizedTime = 0f;
122 while (isActiveAndEnabled) {
124 float idleStartTime = Time.unscaledTime;
127 if (Target.transform.hasChanged) {
128 Target.transform.hasChanged =
false;
129 idleStartTime = Time.unscaledTime;
131 if (activateMode ==
ActivateModeEnum.Auto && Vector3.Distance(Target.transform.position, transform.TransformPoint(targetPos)) > autoActivateRadius) {
134 if (OnTargetActive != null)
138 normalizedTime = (Time.unscaledTime - idleStartTime) / restorePosSpeed;
139 RestoreTarget(normalizedTime);
144 float lastTimeChanged = Time.unscaledTime;
149 if (Target.transform.hasChanged) {
150 lastTimeChanged = Time.unscaledTime;
151 Target.transform.hasChanged =
false;
153 if (Vector3.Distance (Target.transform.position, transform.TransformPoint(targetPos)) > removeRadius) {
157 }
else if (Time.unscaledTime > (lastTimeChanged + activeTimeout)) {
159 float timedOutTime = Time.unscaledTime;
160 while (Time.unscaledTime < timedOutTime + restorePosSpeed) {
161 normalizedTime = (Time.unscaledTime - timedOutTime) / restorePosSpeed;
162 RestoreTarget(normalizedTime);
167 if(OnTargetIdle != null)
175 GameObject originalTarget = Target;
176 originalTarget.transform.parent = null;
177 if (limitDuplicates && numDuplicates >= maxDuplicates) {
181 if (OnTargetEmpty != null)
186 if (OnTargetDuplicateStart != null)
187 OnTargetDuplicateStart();
189 GameObject.Instantiate(originalTarget, transform);
190 Target.name = originalTarget.name;
191 Target.transform.localPosition = targetPos;
192 Target.transform.localRotation = targetRot;
193 float duplicateStartTime = Time.unscaledTime;
194 while (Time.unscaledTime < duplicateStartTime + duplicateSpeed) {
195 normalizedTime = (Time.unscaledTime - duplicateStartTime) / duplicateSpeed;
196 Target.transform.localScale = targetScale * duplicateGrowCurve.Evaluate(normalizedTime);
199 Target.transform.localScale = targetScale;
202 if (OnTargetDuplicateEnd != null)
203 OnTargetDuplicateEnd();
207 if (OnTargetIdle != null)
215 private void OnDrawGizmos() {
219 Gizmos.color = Color.cyan;
220 Gizmos.DrawWireSphere(transform.TransformPoint(targetPos), autoActivateRadius);
224 Gizmos.color = Color.magenta;
225 Gizmos.DrawWireSphere(transform.TransformPoint(targetPos), removeRadius);
232 if (Application.isPlaying) {
236 if (Target != null) {