I use this in CheckReplacement() for detecting the pawn, here for example Cow and BabyCow:
Code: Select all
function bool CheckReplacementScriptedPawn(ScriptedPawn SP) {
local ScriptedPawn NewSP;
local TCollisionFlags OldCollisionFlags;
NewSP = None;
...
if (SP.Class == class'BabyCow')
NewSP = ScriptedPawn(SpawnAndPasteActor(SP, CProjectPrefix $ BabyCowNew, OldCollisionFlags));
else if (SP.Class == class'Cow')
NewSP = ScriptedPawn(SpawnAndPasteActor(SP, CProjectPrefix $ CowNew, OldCollisionFlags));
else if (SkaarjTrooper(SP) != None)
...
And this for spawning the new Pawn:
Code: Select all
function Actor SpawnAndPasteActor(actor Template, coerce string aClassName, out TCollisionFlags OldCollisionFlags) {
/******************************************************************************
Does nearly the same as *ReplaceWith* but returns the spawned Actor.
******************************************************************************/
local Actor A;
local class<Actor> aClass;
local bool bOldCollideActors, bOldBlockActors, bOldBlockPlayers;
if ( Template.IsA('Inventory') && (Template.Location == vect(0,0,0)) )
return None;
aClass = class<Actor>(DynamicLoadObject(aClassName, class'Class'));
if (aClass == None)
{
warn("class '" $ aClassName $ "' could not be loaded.");
return None;
}
else
{
OldCollisionFlags.bCollideActors = Template.bCollideActors;
OldCollisionFlags.bBlockActors = Template.bBlockActors;
OldCollisionFlags.bBlockPlayers = Template.bBlockPlayers;
class'UtilsSB'.static.SetCollisionEx(Template, false, false, false);
A = Spawn(aClass, Template.Owner, Template.tag, Template.Location, Template.Rotation);
if (A == None) // failed: issue a warning, restore old values and exit
{
warn("could not spawn" @ aClassName @ "for Template=\"" $ Template $ "\" at" @ Template.Location);
Template.SetCollision(OldCollisionFlags.bCollideActors, OldCollisionFlags.bBlockActors, OldCollisionFlags.bBlockPlayers);
return None;
}
}
...
Cow0 is replaced without errors.ucc.init.log wrote:KHMBase MH-NaliVillage][.KHMBase0 (Function BarbiesWorld.KHMBase.SpawnAndPasteActor:0195) could not spawn BarbiesWorld.CowSB for Template="MH-NaliVillage][.Cow1" at -946.707764,-3269.600586,-223.899628
KHMBase MH-NaliVillage][.KHMBase0 (Function BarbiesWorld.KHMBase.SpawnAndPasteActor:0195) could not spawn BarbiesWorld.BabyCowSB for Template="MH-NaliVillage][.BabyCow0" at -1002.988831,-3309.318359,-239.899445
I tried the following:
- setting CollisionRadius=0, CollisionHeight=0, bBlockActors=false, bBlockPlayers=false, bCollideActors=false, bCollideWorld=false for the new Cow
- setting CollisionRadius=0, CollisionHeight=0 for the existing cow before spawning the new one
- adding a small z-axes offset to the location for the new cow (avoiding pivot points at the same location)
- destroying the old cow before spawning the new one
I cannot understand why it is not possible to spawn an Actor at any place (even in the void) if it does not interact with anything in the world by setting all collision properties to 0/false?
PS - FYI the code of the new Cow
Code: Select all
class CowSB extends Cow;
function PostBeginPlay() {
local bool OldbHasBaby;
OldbHasBaby = bHasBaby;
bHasBaby = false; // avoid spawning a BabyCow in parent class
Super.PostBeginPlay();
bHasBaby = OldbHasBaby;
// now add the new baby class, if *bHasBaby*:
if (bHasBaby) //add baby
{
Destination = Location;
baby = Spawn(class'BabyCowSB',,, Location + vector(Rotation) * 1.5 * CollisionRadius);
if (baby != None)
baby.mom = self;
}
}
state Grazing {
function EndState() {
/**************************************************************************
BabyCowSB MH-NekonekoHouse.BabyCowSB1 (Function UnrealShare.Cow.Grazing.EndState:0009) Accessed None
**************************************************************************/
if (Enemy != None && Enemy.bIsPlayer) // added "Enemy != None"
MakeNoise(1.0);
JumpZ = Default.JumpZ;
bAvoidLedges = false;
MinHitWall = Default.MinHitWall;
}
}
defaultproperties {
MenuName="Cow"
}