C# Unity3D-让游戏对象用c闪烁#
在我的Unity项目中,我有一个空游戏对象,它有3个子游戏对象。空的游戏对象被称为C# Unity3D-让游戏对象用c闪烁#,c#,unity3d,C#,Unity3d,在我的Unity项目中,我有一个空游戏对象,它有3个子游戏对象。空的游戏对象被称为电缆带,如果相机移动到一个特殊位置,我希望三个子对象的材质开始从白色变为黄色并返回。不幸的是,我所有的解决方案都不起作用 这就是我到目前为止所做的: using UnityEngine public class BlinkingObject : MonoBehaviou { public GameObject CableStrip; public Material white, yellow;
电缆带
,如果相机移动到一个特殊位置,我希望三个子对象的材质开始从白色变为黄色并返回。不幸的是,我所有的解决方案都不起作用
这就是我到目前为止所做的:
using UnityEngine
public class BlinkingObject : MonoBehaviou
{
public GameObject CableStrip;
public Material white, yellow;
public GameObject camManager; //Empty GameObject with the Main Camera
private Vector3 camPosition;
bool blinkObject;
void Update()
{
if(camManager.transform.position == camPosition)
{
InvokeRepeating("Blink", 0, 1);
}
}
public void Blink()
{
Renderer[] colorCable = CableStrip.GetComponentsInChildren<Renderer>(true);
foreach (var cableChild in colorCable)
{
if(blinkObject)
{
cableChild.material = yellow;
blinkObject = false;
} else
{
cableChild.material = white;
blinkObject = true;
}
}
}
}
使用UnityEngine
公共类BlinkingObject:MonoBehavious
{
公共游戏对象电缆带;
公共材料白色、黄色;
公共游戏对象camManager;//使用主摄像机清空游戏对象
私人向量3坐标;
布尔对象;
无效更新()
{
if(camManager.transform.position==camPosition)
{
调用重复(“闪烁”,0,1);
}
}
公共图书馆
{
渲染器[]colorCable=CableStrip.GetComponentsInChildren(true);
foreach(彩色电缆中的var cableChild)
{
如果(闪烁对象)
{
cableChild.material=黄色;
blinkObject=false;
}否则
{
cableChild.material=白色;
blinkObject=true;
}
}
}
}
我怎样才能让我的游戏对象以一种好的方式闪烁
编辑
对不起,错误的定义不起作用。问题是,颜色变化太快。即使我通过调用重复来改变秒数,也不会改变。即使我写invokereepeating(“闪烁”,0,10),它仍然会以毫秒为单位改变颜色代码>问题:
InvokeRepeating("Blink", 0, 1);
被多次调用。因此,每满足一帧条件,就添加一个新的重复调用。。。最终可能会有数千次重复的并行调用
相反,您要做的是在条件满足时启用闪烁,而在条件不满足时禁用闪烁。在这种情况下,我不会使用Invoke
或InvokeReapting
。只需使用计时器即可实现:
private float timer;
private bool blinkObject;
private Renderer[] colorCable;
private void Awake()
{
// you want to do this only once!
colorCable = CableStrip.GetComponentsInChildren<Renderer>(true);
}
private void Update()
{
HandleBlink();
}
// As suggested by Cid you can ofcourse move it all to a method
// so you don't disturb other things happening in Update
private void HandleBlink()
{
// is the condition fulfilled?
var doBlink = camManager.transform.position == camPosition;
// if not do nothing
if(!doBlink) return;
// reduce the timer by time passed since last frame
timer -= Time.deltaTime;
// if timer not under 0 do nothing else
if(timer > 0) return;
// If timer exceeded invert the blinkObject flag
blinkObject = !blinkObject;
foreach (var cableChild in colorCable)
{
// Shorthand for if(blinkObject) { ... = yellow; } else { ... = white; }
cableChild.material = blinkObject ? yellow : white;
}
// and reset the timer
timer = 1f;
}
专用浮点计时器;
私有布尔对象;
专用电缆;
私人空间
{
//你只想这样做一次!
colorCable=CableStrip.GetComponentsInChildren(true);
}
私有void更新()
{
把手连杆();
}
//正如Cid所建议的,您当然可以将其全部移动到一个方法中
//所以,您不会干扰更新中发生的其他事情
专用无效把手链接()
{
//条件满足了吗?
var doBlink=camManager.transform.position==camPosition;
//如果不是什么都不做
如果(!doBlink)返回;
//按从上一帧开始经过的时间减少计时器
timer-=Time.deltaTime;
//如果计时器不低于0,则不执行其他操作
如果(计时器>0)返回;
//如果超过计时器,则反转blinkObject标志
blinkObject=!blinkObject;
foreach(彩色电缆中的var cableChild)
{
//if(blinkObject){…=黄色;}else{…=白色;}的缩写
cableChild.material=blinkObject?黄色:白色;
}
//然后重置计时器
定时器=1f;
}
或者,同样的事情也可以通过使用一种通常更干净的方法来实现(但这只是观点):
//用于防止并发例程的标志
私家侦探在眨眼;
专用电缆;
私人空间
{
//你只想这样做一次!
colorCable=CableStrip.GetComponentsInChildren(true);
}
私有void更新()
{
//条件满足了吗?
if(camManager.transform.position==camPosition)
{
如果(!isBlinking)启动例行程序(BlinkRoutine());
}
其他的
{
StopAllCoroutines();
isBlinking=false;
}
}
私有IEnumerator例程()
{
isBlinking=true;
var-blinkObject=false;
//这看起来很吓人,但在协同程序中很好
//只要你在内心的某个地方屈服!
while(true)
{
blinkObject=!blinkObject;
foreach(彩色电缆中的var cableChild)
{
//if(blinkObject){…=黄色;}else{…=白色;}的缩写
cableChild.material=blinkObject?黄色:白色;
}
返回新的WaitForSeconds(1);
}
}
问题:
InvokeRepeating("Blink", 0, 1);
被多次调用。因此,每满足一帧条件,就添加一个新的重复调用。。。最终可能会有数千次重复的并行调用
相反,您要做的是在条件满足时启用闪烁,而在条件不满足时禁用闪烁。在这种情况下,我不会使用Invoke
或InvokeReapting
。只需使用计时器即可实现:
private float timer;
private bool blinkObject;
private Renderer[] colorCable;
private void Awake()
{
// you want to do this only once!
colorCable = CableStrip.GetComponentsInChildren<Renderer>(true);
}
private void Update()
{
HandleBlink();
}
// As suggested by Cid you can ofcourse move it all to a method
// so you don't disturb other things happening in Update
private void HandleBlink()
{
// is the condition fulfilled?
var doBlink = camManager.transform.position == camPosition;
// if not do nothing
if(!doBlink) return;
// reduce the timer by time passed since last frame
timer -= Time.deltaTime;
// if timer not under 0 do nothing else
if(timer > 0) return;
// If timer exceeded invert the blinkObject flag
blinkObject = !blinkObject;
foreach (var cableChild in colorCable)
{
// Shorthand for if(blinkObject) { ... = yellow; } else { ... = white; }
cableChild.material = blinkObject ? yellow : white;
}
// and reset the timer
timer = 1f;
}
专用浮点计时器;
私有布尔对象;
专用电缆;
私人空间
{
//你只想这样做一次!
colorCable=CableStrip.GetComponentsInChildren(true);
}
私有void更新()
{
把手连杆();
}
//正如Cid所建议的,您当然可以将其全部移动到一个方法中
//所以,您不会干扰更新中发生的其他事情
专用无效把手链接()
{
//条件满足了吗?
var doBlink=camManager.transform.position==camPosition;
//如果不是什么都不做
如果(!doBlink)返回;
//按从上一帧开始经过的时间减少计时器
timer-=Time.deltaTime;
//如果计时器不低于0,则不执行其他操作
如果(计时器>0)返回;
//如果超过计时器,则反转blinkObject标志
blinkObject=!blinkObject;
foreach(彩色电缆中的var cableChild)
{
//if(blinkObject){…=黄色;}else{…=白色;}的缩写
cableChild.material=blinkObject?黄色:白色;
}
//然后重置计时器
定时器=1f;
}
或者,同样的事情也可以通过使用清洁剂来实现