속성 변경
* 퓨전 프로퍼티에 대한 테스트를 하던 도중 스크립트에 문제가 생겨 새로 만들었습니다.
Player 스크립트
Netwrked는 메서드의 오버로딩처럼 파라미터를 넣는 버전이 있는듯하다.
public class Player : NetworkBehaviour
{
// Networked 속성의 파라미터로 OnChanged라는 string 프로퍼티가 있는데
// OnChanged는 'static void OnChanged(Changed<MyClass> changed){}' 형식의 콜백이다.
[Networked(OnChanged = nameof(OnBallSpawned))]
// NetworkBool처럼 true false 값이 두 가지만 있는 경우 변경사항이 감지되지 않을 수가 있으므로
// byte/int 로 대체하고 호출할 때마다 값을 변경하는 방식으로 할수도 있다. (시각적 효과와 대역폭의 소모 중요도 차이)
public NetworkBool spawned { get; set; }
여기선 자식의 Meshrenderer에서 Material을 찾아 따로 Material프로퍼티를 만들어주는데 이 프로젝트의 경우 Player의 Cube 메시를 Player스크립트가 있는 부모와 구분해 자식으로 가게 했으므로 자식에서 찾는 GetComponentInChildren으로 찾아오는 것 같다. -> 매번 가져오지 않고 한 번만 세팅하기 위함
Material _material;
Material material
{
get
{
if (!_material)
{
_material = GetComponentInChildren<MeshRenderer>().material;
}
return _material;
}
}
위의 Networked속성의 파라미터 형식대로 함수를 만들었다.
여기서 spawned 값이 바뀐 Player의 material의 color를 흰색으로 바꿔준다.
// struct인 Changed<T>의 T는 NetworkBehaviour를 상속받는 컴포넌트이다.
public static void OnBallSpawned(Changed<Player> changed)
{
// changed.Behaviour가 T이다. (여기선 Player)
changed.Behaviour.material.color = Color.white;
}
이전에 가져온 material의 Color를 Color.Lerp를 통해 현재 컬러에서 목표 컬러까지 Time.deltaTime 비율만큼 부드럽게 변하게 만들었다.
// NetworkBehaviour를 상속하는 SimulationBehaviour에 있는 메서드이다.
// 색 변화 등을 Update가 아니라 Render에서 수행하는 이유는
// Render()가 퓨전의 FixedUpdateNetwork 이후에 호출되는 것이 보장되기 때문이다.
// 또한 Runner.DeltaTime이 아니라 Time.deltaTime을 사용하는 이유는
// 렌더링 자체는 Fusion 시뮬레이션 단위인 Runner.DeltaTime이 아니고
// 유니티의 render loop에서 실행되어서 그렇다.
public override void Render()
{
material.color = Color.Lerp(material.color, Color.blue, Time.deltaTime);
}
이후에 FixedUpdateNetwork의 마지막 부분에 spawned = !spawned를 추가하여 토글로 공을 생성할 때마다 값이 바뀌게 했다.
public override void FixedUpdateNetwork()
{
if(GetInput(out NetworkInputData data))
{
data.direction.Normalize();
_cc.Move(5 * data.direction * Runner.DeltaTime);
if (data.direction.sqrMagnitude > 0)
_forward = data.direction;
if (delay.ExpiredOrNotRunning(Runner))
{
if ((data.buttons & NetworkInputData.MOUSEBUTTON1) != 0)
{
delay = TickTimer.CreateFromSeconds(Runner, 0.5f);
Runner.Spawn(_prefabBall,
transform.position+_forward, Quaternion.LookRotation(_forward),
Object.InputAuthority, (runner, o) =>
{
// Initialize the Ball before synchronizing it
o.GetComponent<Ball>().Init();
});
}
else if ((data.buttons & NetworkInputData.MOUSEBUTTON2) != 0)
{
delay = TickTimer.CreateFromSeconds(Runner, 0.5f);
Runner.Spawn(_prefabPhysxBall,
transform.position+_forward,
Quaternion.LookRotation(_forward),
Object.InputAuthority,
(runner, o) =>
{
o.GetComponent<PhysxBall>().Init( 10*_forward );
});
}
spawned = !spawned;
}
}
}
'공부 모음 > 포톤 퓨전 시작해보기' 카테고리의 다른 글
포톤 퓨전 원격 프로시져 호출(RPC) (0) | 2022.12.09 |
---|---|
포톤 퓨전 물리 (2) | 2022.12.08 |
포톤 퓨전 Prediction (0) | 2022.12.08 |
포톤 퓨전 시작하기, 씬 설정하기 (0) | 2022.12.07 |