Jump to content

  • Log In with Google      Sign In   
  • Create Account

mr_malee

Member Since 18 Oct 2007
Offline Last Active Aug 22 2014 02:08 PM

#5149701 Rotate character spine so weapon aims at target

Posted by mr_malee on 26 April 2014 - 01:52 PM

solved it using iteration.

Also, had to project weapon forward onto spines forward plane as the origin.

 

added clamping and smoothing too: :)

Transform s = spine;
Transform w = weapon.transform;

float distance = float.PositiveInfinity;
float minDistance = 0.01f;
int iteration = 30;

Quaternion oldRotation = lastAimRotation;

while (distance > minDistance && iteration > 0) {

	Vector3 aimOrigin = w.TransformPoint(weapon.attackPoint);
	Vector3 origin;

	if (!LinePlaneIntersection(out origin, aimOrigin, -w.forward, s.forward, s.position)) {

		//if for some readon the weapon cannot intersect with spine forward plane, just use the aim origin
		//hopefully this never happens as weapon should always be in front of spine
		
		origin = aimOrigin;
	}

	Vector3 weaponForward = w.forward;
	Vector3 aimForward = target - origin;

	Quaternion rot = Quaternion.FromToRotation(weaponForward, aimForward);

	distance = rot.eulerAngles.sqrMagnitude;
	iteration--;

	s.rotation = rot * s.rotation;
}

//clamp angles

Vector3 angles = s.localEulerAngles;

//offset the clamped angles by any upper body offset
//we may need this if characters aren't aligned forward when rotation is identity

angles.x = ClampAngle(angles.x, minUpperBodyAngles.x + upperBodyAngleOffset.x, maxUpperBodyAngles.x + upperBodyAngleOffset.x);
angles.y = ClampAngle(angles.y, minUpperBodyAngles.y + upperBodyAngleOffset.y, maxUpperBodyAngles.y + upperBodyAngleOffset.y);
angles.z = ClampAngle(angles.z, minUpperBodyAngles.z + upperBodyAngleOffset.z, maxUpperBodyAngles.z + upperBodyAngleOffset.z);

s.localEulerAngles = angles;

//smooth if we have easing

if (aimRotationEasing > 0) {

	s.rotation = Quaternion.Slerp(lastAimRotation, s.rotation, Time.deltaTime * aimRotationEasing);
	lastAimRotation = s.rotation;
}
private static float ClampAngle(float ang, float min, float max) {

	if (ang > 180) ang -= 360;
	if (max > 180) max -= 360;
	if (min > 180) min -= 360;

	ang = Mathf.Clamp(ang, min, max);

	return ang < 0 ? ang + 360 : ang;
}
private static bool LinePlaneIntersection(out Vector3 intersection, Vector3 linePoint, Vector3 lineVec, Vector3 planeNormal, Vector3 planePoint) {

	float dotNumerator = Vector3.Dot(planePoint - linePoint, planeNormal);
	float dotDenominator = Vector3.Dot(lineVec, planeNormal);

	if (dotDenominator != 0.0f) {

		intersection = linePoint + lineVec.normalized * (dotNumerator / dotDenominator);
		return true;
	}
	else {
		
		intersection = Vector3.zero;
		return false;
	}
}



#5096761 Calculate best car gear

Posted by mr_malee on 25 September 2013 - 01:33 PM

I ended up with something like this:

//find the current gear ratio
float currentRatio = gearRatios[currentGear];

if (currentRatio > 0) {

	float bestDist = float.PositiveInfinity;
	int bestGear = currentGear;
	
	int i, len = gears.Length;
	
	//start at index 2 (gear 1)
	//index 0 = reverse
	//index 1 = neutral

	for (i = 2; i < len; i++) {
	
		//find the gear ratio and the ratio to move into this gear from the current
		float gearRatio = gearRatios[i];
		float moveRatio = gearRatio / currentRatio;
		
		//find Optimal rpm. These are pre-calculated for each gear. They are generally around the redline mark (8000rpm for my car)
		float rpmOptimal = optimalRPM[i];
		
		//find the next rpm which the engine would produce if moving into this gear		
		float rpmNext = moveRatio * currentRPM;
		
		//find distance between optimal and next		
		float rpmDist = rpmOptimal - rpmNext;
		
		//if the next rpm is < maxRPM, the distance is above 0 (hasn't crossed optimal) and is < the current best, then this is a contender for the best gear

		if (rpmNext < maxRPM && rpmDist >= 0 && rpmDist < bestDist) {

			bestDist = rpmDist;
			bestGear = i;
		}
	}
}

So far it's working nicely. 




#5096334 Calculate best car gear

Posted by mr_malee on 23 September 2013 - 10:55 PM

thanks for the reply. However, I'm looking at something that can give me an instant estimate.

 

The reason being that the gear is used as an indication/guide to the player so that they can change gears appropriately. 

 

The player needs almost instant feedback so they can make the required actions.




PARTNERS