[Solved] Dual-Actor rotation comparison math

Discussions about Coding and Scripting
ShaiHulud
Adept
Posts: 459
Joined: Sat Dec 22, 2012 6:37 am

Re: Vector/single rotation comparison math

Post by ShaiHulud »

I'm following this thread with interest because - in own more remedial way - I'm struggling with some of the same problems at the moment. But just now I'm stuck on one thing in particular. I'm trying to modify bot behaviour, and I've been doing some testing to see what's achievable. At the moment I just want a bot to rotate by an angle that I specify. This happens... but then the bot immediately re-adjusts to its previous vector, and I've no idea why.

I'm inheriting from HumanBotPlus.uc, and messing about with the PlayRunning function. Here (at the start of the function) I've inserted a "GotoState", and then I have something like:

Code: Select all

....
  Begin:
    Acceleration = vect(0, 0, 0); // Halt current movement
    TurnTo(Destination);
    myRot = Rotation; // 'myRot' is a global rotator
    myRot.Yaw += (90 * 182.0444); // Turn clockwise 90 degrees: apparently the UDK defines some useful constants for calculations like this*
    SetRotation(myRot);
    Sleep(5); // Sleep 5 seconds so that I can observe the change
*page with useful constants http://romerounrealscript.blogspot.co.u ... cript.html

I've also tried:

Code: Select all

....
  Begin:
    Acceleration = vect(0, 0, 0);
    myVec = Destination - Location; // myVec is a global vector
    myRot = rotator(myVec);
    myRot.Yaw += (90 * 182.0444);
    SetRotation(myRot);
    Sleep(5);
I run the game with a 'slomo' setting that allows me to study what's happening more easily, and in each case the bot momentarily spins around by 90 degrees, but then instantly returns to its previous orientation. Any idea why this might be?
User avatar
ANUBITEK
Adept
Posts: 261
Joined: Sun Dec 28, 2014 1:10 am
Location: Anubitek

Re: [Solved] Dual-Actor rotation comparison math

Post by ANUBITEK »

//============================================================================
This should work as a good example for checking the positions between two Actors and comparing rotations.
Register Tick

Code: Select all

event Tick( float DeltaTime)
{
	local [CAMERA]	LocalCam;
	local [ACTOR] TargetActor;
	local Vector V, X, Y, Z;
	local rotator R;
	local byte SpriteIndex;
	local int i, j, Max;

	ForEach AllActors (class'[INSERT VIEWPORT-OWNER HERE]', LocalCam)
	{
		if ( LocalCam == none )
			return;
		break;
	}
	[...]
	if ( TargetActor != none && TargetActor .DrawType == DT_Sprite
		&& LocalCam != none )
	{
		AdjustDirIndex(TargetActor, LocalCam, SpriteIndex);
	[...]
Sprite Rotation Code

Code: Select all

final function int AdjustDirIndex(Actor SpritePawn, [VIEWPORT OWNER] Camera,  out int AnimDir)
{
	local Rotator	R1,R2;
//	MAX_WORD is 0b1111111111111111 (65535, 16 bits)
//	MAX_DIR is 0b0000000000000111 (7, 3 bits)

	R1 = sAnimated.Rotation;
	R2 = Rotator(Camera.Location - sAnimated.Location);
	
	AnimDir = ( ( (R1.Yaw - R2.Yaw) & 65535) + 4096) >> 13;

	return AnimDir;
}
If you want some more info on this beyond the solution to grabbing the rotation values, head to this topic:
viewtopic.php?f=15&t=11730&p=94432#p94432
//============================================================================

So I shelved the code I was working on, which was doing what I needed based on if the actor was facing "North", but any other direction and I would yield strange results.

I found the "Old Scrap Code" below was checking between the range of 1.0 and -1.0 based on the relative position of the camera to the actor, 1.0 being the front of the actor that was being tracked for sprite changes, and behind the actor was -1.0 (if you were 45 degrees to the actor on either its left or right, you would get a 0.0).

I'm willing to bet that this could have easily been fixed, but as Gustavo pointed out, if the Camera was above the actor in question, I got a dot result that made the sprite act strangely because I THINK that it is doing the math independent of certain limits that should restrict results that occur due to vertical position of camera to the tracked actor, but I have no idea how to do that. Why does it do this by the way? I have more questions about how Dot product works in Unrealscript if anyone wants to discuss it.
Old Scrap Code

Code: Select all

	/*if ( (X dot Normal(V) >=  0.75) && (X dot Normal(V) <= 1.0) ) // 0.125
	{
		SpriteIndex = 1;
		log("1: "$ X dot Normal(V));
	}
	if ( (X dot Normal(V) >= 0.25) && (X dot Normal(V) < 0.75) ) // 0.25
	{
		SpriteIndex = 2;
		log("2: "$ X dot Normal(V));
	}
	if ( (X dot Normal(V) >= -0.25) && (X dot Normal(V) < 0.25) ) // 0.25
	{
		SpriteIndex = 3;
		log("3: "$ X dot Normal(V));
	}
	if ( (X dot Normal(V) >= -0.75) && (X dot Normal(V) < -0.25 ) ) // 0.125
	{
		SpriteIndex = 4;
		log("4: "$ X dot Normal(V));
	}
	if ( (X dot Normal(V) >= -1.0) && (X dot Normal(V) < -0.75 ) ) // 0.125
	{
		SpriteIndex = 5;
		log("5: "$ X dot Normal(V));
	}
<<| http://uncodex.ut-files.com/ |>>

Code reference for UGold, UT99, Unreal2, UT2k3, UT3
Additional Beyond Unreal Wiki Links
wiki.beyondunreal.com/Legacy:Console_Bar
wiki.beyondunreal.com/Exec_commands#Load
wiki.beyondunreal.com/Legacy:Exec_Directive#Loading_Other_Packages
wiki.beyondunreal.com/Legacy:Config_Vars_And_.Ini_Files
wiki.beyondunreal.com/Legacy:INT_File
Post Reply