| Home Page | Recent Changes

VitalOverdose/VecTagger

UT2004 :: Actor >> Trigger >> vecbooster (Package: custom)

by VitalOverdose

Part of Vital'sPMT

Overview

A VecTagger is a trigger actor that can dynamically spawn an emitter and hard attach it to the actor that initiated the event.

This is great for adding realism when a player walks though fire or accross lava etc.

The script

To start off we need to grab a valid Actor ref to the vehicle that initiated the event. Once we have a valid actor ref we can then spawn an emitter and tell the emitter to attach itself to the actor that initiated the event by using the ValidActor ref that is passed to the function Touch() that gets called when two actor collide.We dont need to change the code for the touch() function itself just add some of out own code to the start of the function. This way our code gets run first and then the rest of the function plays through normaly.

Function Touch(actor other)
{
// The code for processing the touch function would go here.
}

broken down is the same as

WhenTouchedSendMeINfo(TypeOfInfoToRecieve WhatToStoreItIn)
{
// The code for processing the touch function would go here.
}

Positioning the inserted code

super.

Rather than having to copy all the original code and pasting it in after out new code so that the function still works correctly we can use a function called .Super which efectivly does the same thing but the reduced amount of code makes identifying the modifications and their positioning reletive to the existing code from the parent function a lot easyier.

WhenTouchedSendMeINfo(TypeOfInfoToRecieve,VariableToUseAsARefference)
{
// New code to run before the existing code from the parent
super.touch(other)   // Same as all the code from the parent function. 
}

or

WhenTouchedSendMeINfo(TypeOfInfoToRecieve,VariableToUseAsARefference)
{
super.touch(other)   // Same as all the code from the parent function. 
// New code to run afterthe existing code from the parent

}

Touch()

When touched a ValidActor refference to the actor that causes the Touch event is stored in the variable called 'other'.

so now if we want to 'do' anything to that actor we just use 'other' as if it was that actor itself.

Whatever we do to 'Other' will get updated to the actual actor.

Spawn()

Heres whats needed to spawn an emitter actor.

Spawn( class< emitter > );

but there are also some extra 'Optional' properties that you can set;-

Spawn( class< emitter > , owner, tag , location , rotation );

once we have our ValidActor stored in Other we can access some of its properties and then use them in the actual call to spawn itself. This is how we can get the emitter to spawn at the location of the touch using 'Other.location'.

Function Touch(actor other)
{
Spawn( class< emitter > , other, tag , other.location , other.rotation );
}

Im also making Other the Owner of that actor by using the ref 'other' right after the class type (class< emitter >).

The next field is for adding a tag name to the newly spawned actor. This isnt much use here so i just leave it blank.

Function Touch(actor other)
{
local emitter WhatGotSpawned;         // To use to refference to what gets spawned
local class< emitter > EmitterClass;   // The intended class type of what gets spawned
local vector RotationOfWhatTouchedUs; // Hold a ref to the rotation of the actor that touched us   
local vector LocationOfWhatTouchedUs; // Hold a ref to the Location of the actor that touched us 

EmitterClass=class"NewRedeemerTrail";

WhatGotSpawned = Spawn(EmitterClass, other, ,LocationOfWhatTouchedUs, RotationOfWhatTouchedUs );
}

If we want to let the mapper choose the emitter type to spawn we need to create a Global Variable rather than a local one to hold the ref to the required actor class. this is done by adding a 'Variable Decleration' to the top of the new script

This will be accessable through the normal properties window in unrealed and we can name it whever we want as long as its not a restricted name. Ill call this one SpawnFxClass

var() class< emitter >                 SpawnFXClass;

Note:Putting the ( and ) after 'var' makes the property available in unrealed to the mapper at map creation time.This will have an initial property of 'None' untill set by the mapper or assigned a value in the default properties.

The chosen Emitter class can now be reffered to by the variable called'SpawnFX' and is the final bit of info we need for the spawn in Touch.

var() class< emitter >                 EmitterClass;

Function Touch(actor other)
{
local emitter WhatGotSpawned;
WhatGotSpawned = Spawn( EmitterClass, other, , other.location , other.rotation );
}

so now the trigger that will spawn emitters when touched by a valid actor.

To attach the emitter to whatever touched us we need a 'Valid Actor ref' for the spawned emitter and that gets passed to the function and stored in the variable of actor type 'other'

Spawn continued..

If assigned to a variable of the same type as the one your spawning the function 'Spawn' returns a ValidActor ref to whatever its spawns.This valid ref can then be used if we want to 'do' anything to that actor elsewhere in the code.Also this can be used to check to see if the actor has spawned correctly. If the spawn function returns 'none' then we know something is wrong.

Example:

var() class< emitter >                 EmitterClass;

Function Touch(actor other)
{
local emitter WhatGotSpawned;
WhatGotSpawned=Spawn( EmitterClass, other, , other.location , other.rotation );
}

Setbase(actorToStickTo);

Once we have the valid actor ref for the emitter we can now tell make it stick to whatever touched us with the setbase() function.

WhatGotSpawned.setbase();

To make it stick to what touched us add ;-

WhatGotSpawned.setbase(other);

At the moment this actor will attempt to spawn an emitter and then attach it to ANYTHING that triggers the 'Touch()' function.With emitters attaching to other emitters things can can get a bit hectic and it would certainly have a significant impact on the overall game speed. This can be sorted out by introducing a check to see if what touches it is of the right player class to start off with. For this all the moving actors (except movers) that would be player,monster,bot or vehicle.Because player,monster,bot and onsvehicle are all children of the Actor Class 'Pawn' we can just test to see if what touched us was a 'Pawn'.This can be done by testing what gets returned by the function :

Complete Script

//=============================================================================
// FxTagger By vitaloverdose, Feb 2006, http://www.Vitaloverdose.com
// This is part of the 'Vitals Pro Mapping Tools' Mod 
// Full class list http://wiki.beyondunreal.com/wiki/Vital's_Pro_Mapping_Tools
// Direct Download the Mod in zipped format Http://promappingtools.zapto.org
//=============================================================================

class FxTagger extends trigger
Placeable;

var() class<emitter>                 SpawnFX;

Function Touch(actor other)
{
local emitter WhatJustGotSpawned;
if (other.isa('pawn')) 
   {
   WhatJustGotSpawned=Spawn( SpawnFX , other, , other.location , ther.rotation );
   WhatJustGotSpawned.setbase(other);
   }
}

Its tighter coding and not as easy to read as the first method. Its all personal pref.

In this revision the VecTagger checks to see if the vec is allready tagged.Also it includes a check to see if the emitter actually gets spawned before attempting to attach it to whatever triggered the Touch function.

//=============================================== 
// FxTagger By vitaloverdose, Feb 2006, http://www.Vitaloverdose.com
// This is part of the 'Vitals Pro Mapping Tools' Mod 
// Full class list http://wiki.beyondunreal.com/wiki/Vital's_Pro_Mapping_Tools
// Direct Download the Mod in zipped format Http://promappingtools.zapto.org
//=============================================== 

class VecFxTagger extends trigger 
Placeable; 

var() class<emitter>                 SpawnFX; 

Function Touch(actor other) 
{ 
local emitter WhatGotSpawned; 
local Int I;
 
if (!other.isa('pawn'))
    for (I=0;I<other.attached.length;I++) 
         if (other.attached[i].class!=class'emitter') 
             WhatGotSpawned = Spawn( SpawnFX , other, , other.location , other.rotation ); 
             if (WhatGotSpawned != None)
                 WhatGotSpawned.setbase(other); 
} 

Unfortunatley this method of spawning emitters in a game will only work in single player mode.

Here is a link to a .uc file for this script;-

[Download .U File]

Getting it to work online

The problem is that the call to 'spawn' emitters is not automaticly replicated to the client computers so only people playing on the server would be able to see it.

My first attempt at getting this to work online has not been all the sucessful.

I cant seem to find any good examples of emiters spawning online to give me any clues as to how this should be done correctly. Ive had some sucess in getting a replicated call to the client ok but still no spawn :(

This is what i have put together so far;-

class VecFxTagger extends trigger
Placeable;

Var () class< Emitter >                  FXClass;
Var () Emitter                           SpawnedEmitter;

  replication {
               reliable
               if (bNetDirty  &&  role == role_authority)
                   SpawnedEmitter;

               reliable
               if ( role == role_authority )
                    theTag;
              }

 Simulated Function Touch(Actor Other)
{
if (other.isa('Vehicle'))
     Thetag(vehicle(other));
super.Touch( Other );
 }

 simulated function Thetag(vehicle thevec)
 {
  local Int I;

  for (i= 0 ;I<thevec.attached.length;i++ )
      {
       If (!thevec.attached[i].isa('Emitter'))
          {
           While ( SpawnedEmitter == None )
                 {
                  SpawnedEmitter=Spawn( FXClass ,  thevec, ,  thevec.Location ,  thevec.Rotation ) ;
                  SpawnedEmitter.SetBase( thevec );
                 }
           }
        }
 }

Defaultproperties
{
bGameRelevant=true
RemoteRole=Role_SimulatedProxy
bStatic=False
NetUpdateFrequency=1.000000
}

Vitaloverdose ....I've got no idea why its not working.Ive tried many combinations of different variable replication conditions as well as replicating the function names + swapping around with the properties RemoteRole/bStatic/bGameRelevant. Im quite suprised there arent any tutorials explaing how this can be done.

Related Topics

VitalOverdose/VecBooster

VitalOverdose/VehicleTeleporter

VitalOverdose/RandomRelocator

 

 

Discussion

Category Custom Class

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

FAQs

Help Desk

Mapping Topics

Mapping Lessons

UnrealEd Interface

UnrealScript Topics

UnrealScript Lessons

Making Mods

Class Tree

Modeling Topics

Chongqing Page

Log In