class RayVisualizer extends Emitter placeable; var vector StartEffect, EndEffect; //---------- var rotator BeamDirection; //Relative Beam Direction var float BeamLength; //Beam Length var bool bFloorCorrection; //if we should adjust ray according to floor normal var bool bHit; var bool bLastHitState; simulated event PostBeginPlay() { ParticleSystemComponent.SetHidden(false); //ParticleSystemComponent.SetTemplate(ParticleSystem'WP_LinkGun.Effects.P_WP_Linkgun_Altbeam_Blue'); ParticleSystemComponent.SetTickGroup( TG_PostUpdateWork ); ParticleSystemComponent.SetDepthPriorityGroup(SDPG_World); ParticleSystemComponent.bUpdateComponentInTick = true; ParticleSystemComponent.SetIgnoreOwnerHidden(TRUE); ParticleSystemComponent.SetScale(0.5f); Super.PostBeginPlay(); } replication { if (Role == ROLE_Authority) StartEffect, EndEffect, BeamDirection, BeamLength, bFloorCorrection, bHit; } simulated function SetBeamLocation() { StartEffect = Instigator.Location; SetLocation(Instigator.Location); } simulated function Vector SetBeamRotation() { local vector FloorLocation, FloorNormal; local vector RealRayDirection; RealRayDirection = vector(Instigator.Rotation + BeamDirection); //we have to take into account also angle of the floor we are standing on if (bFloorCorrection) { FloorNormal = vect(0,0,0); Trace(FloorLocation,FloorNormal, Instigator.Location + vect(0,0,-100), Instigator.Location, false, ,); RealRayDirection += FloorNormal * (RealRayDirection dot FloorNormal) * -1; } EndEffect = StartEffect + (RealRayDirection * BeamLength); SetRotation( Rotator(EndEffect - Location) ); return Normal(EndEffect - Location); } simulated function Tick(float dt) { // set beam start location, rotation if (Instigator != none) { //instigator may not be seen at the moment, so won't be replicated SetBeamLocation(); SetBeamRotation(); changeRay(bHit); ParticleSystemComponent.SetVectorParameter('LinkBeamEnd', EndEffect); //ParticleSystemComponent.SetBeamEndPoint(0, EndEffect); } } simulated event Destroyed() { //loginternal("RayVisualizer.Destroyed()"); super.Destroyed(); } simulated function changeRay(bool bHit) { ParticleSystemComponent.DeactivateSystem(); if (bHit && !bLastHitState) { ParticleSystemComponent.SetTemplate(ParticleSystem'WP_LinkGun.Effects.P_WP_Linkgun_Altbeam_Red'); bLastHitState = true; } else if (!bHit && bLastHitState) { ParticleSystemComponent.SetTemplate(ParticleSystem'WP_LinkGun.Effects.P_WP_Linkgun_Altbeam_Blue'); bLastHitState = false; } ParticleSystemComponent.ActivateSystem(); } DefaultProperties { TickGroup=TG_DuringAsyncWork bNetInitialRotation=true RemoteRole=ROLE_SimulatedProxy Begin Object Name=ParticleSystemComponent0 Template=ParticleSystem'WP_LinkGun.Effects.P_WP_Linkgun_Altbeam_Blue' End Object ParticleSystemComponent=ParticleSystemComponent0 bStatic=false bNoDelete=false bReplicateInstigator=true }