Download

Volume collision detection

I’ve made a camera volume that activates the chosen camera type with settings from the volume’s properties. It works fine… until I need to place multiple volumes close to each other. Yeah, there’s the proplem with Touch event when player moves his character to another camera volume before the previous one is untouched. At this state I can go back inside the first volume, and of course, Touch event will never happen.
I know that PhysicsVolumes have their own collision event, but using these volumes as a parent class is not a solution in my case.
Are there any way to implement their PhysicsVolumeChanged for my camera volumes?

Not sure I understand your use case entirely. In any case you can just manually maintain a list of camera volumes you’re in.

Something like this (untested and not compiled). At any point between Touch/UnTouch you can easily access all camera volumes you’re in (in the order they were entered):


var array<YourCameraVolumeClass> CameraVolumes;

event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
	local YourCameraVolumeClass TouchedCameraVolume;

	TouchedCameraVolume = YourCameraVolumeClass(Other);
	if (TouchedCameraVolume != none)
	{
		//optional: do something with the previous camera volume(s) (if one exists)

		//add touched camera volume to the list (make room in array first so we don't get array access out of bounds)
		CameraVolumes.Length = CameraVolumes.Length + 1;
		CameraVolumes[CameraVolumes.Length - 1] = TouchedCameraVolume;

		//optional: do something when you enter a volume
	}
	else
	{
		Super.Touch(Other, OtherComp, HitLocation, HitNormal);
	}
}

event UnTouch( Actor Other )
{
	local YourCameraVolumeClass TouchedCameraVolume;

	TouchedCameraVolume = YourCameraVolumeClass(Other);
	if (TouchedCameraVolume != none)
	{
		CameraVolumes.RemoveItem(TouchedCameraVolume);
	}
	else
	{
		Super.UnTouch(Other);
	}
}

defaultproperties
{
	CameraVolumes.Empty;
}

I was thinking to keep the list of touching volumes, but didn’t realized the importance of their order in that array. Many thanks!

Here is the solution of collision problem. When a volume is untouched, this script removes it from array and simulates Touch event for the last touched volume of the same class. Pretty simple.

Volume subclass


event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal)
{
	if (Legend_Pawn_Player(Other) != None)	
	{
		Legend_Pawn_Player(Other).VolumeTouched(self);
	}
}

event UnTouch(Actor Other)
{
	if (Legend_Pawn_Player(Other) != None)	
	{
		Legend_Pawn_Player(Other).VolumeUnTouched(self);
	}
}

function VolumeTouched(Legend_Pawn_Player P);

Pawn subclass


var array<LZ_Volume> TouchingVolumes;

function VolumeTouched(LZ_Volume V)
{
	TouchingVolumes.AddItem(V);
	TouchingVolumes[TouchingVolumes.Length-1].VolumeTouched(self);
}

function VolumeUnTouched(LZ_Volume V)
{
	local LZ_Volume Volume, LastVolume;
	
	TouchingVolumes.RemoveItem(V);
	
	Foreach TouchingVolumes(Volume)
	{
		if (ClassIsChildOf(Volume.class, V.class))
		{
			LastVolume = Volume;
		}
	}
	if (LastVolume != None)
		LastVolume.VolumeTouched(self);
}