Re: Z - axis movement
I pt a public Transform in the Camera Script, and assigned the camPointer from the ControlScript. Im looking at some of hte Unity cam scripts now. MouseOrbitimproved looks promising.
Universal Fighting Engine Forum Due to increased bot activity, we have discontinued support through the forum. For assistance, questions, and community discussions, please join our official Discord server |
You are not logged in. Please login or register.
Universal Fighting Engine Forum → UFE 1 Source (Deprecated) → Z - axis movement
I pt a public Transform in the Camera Script, and assigned the camPointer from the ControlScript. Im looking at some of hte Unity cam scripts now. MouseOrbitimproved looks promising.
Vector3 target = (P1Trans.position - P2Trans.position);
Vector3 Perpendicular = Vector3.Cross(target, Vector3.up);
midPoint = (P1Trans.position + P2Trans.position) * 0.5f;
if (UFE.config.cameraOptions.followJumpingCharacter)
midPoint.y += Mathf.Abs(P1Trans.position.y - P2Trans.position.y) / 2;
float dist = Vector3.Distance(P1Trans.position, P2Trans.position) * distScale;
dist = Mathf.Clamp(dist, UFE.config.cameraOptions.minZoom, UFE.config.cameraOptions.maxZoom);
Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, UFE.config.cameraOptions.initialFieldOfView, Time.deltaTime * UFE.config.cameraOptions.smooth);
if (Physics.Raycast(Camera.main.transform.position, -Camera.main.transform.forward, 10))
{
dist -= 10;
}
Debug.DrawRay(Camera.main.transform.position, -Camera.main.transform.forward * 10, Color.red);
Camera.main.transform.position = Vector3.Lerp(Camera.main.transform.position, midPoint + Perpendicular.normalized * dist, Time.deltaTime * UFE.config.cameraOptions.smooth);
Quaternion rotation = Quaternion.LookRotation(midPoint - Camera.main.transform.position);
Camera.main.transform.rotation = Quaternion.Lerp(Camera.main.transform.rotation, rotation, Time.deltaTime * UFE.config.cameraOptions.smooth);
I'm using this code to get the camera to follow the mid point between the characters.
The problem seems to be getting the camera to smoothly move forward after the ray intersects with a wall. I need to set the zoom distance based on the midpoint, but at the moment, it just jitters back and forward.
The camera needs to smoothly move away from the wall, then hold that position.
I also revisited the old, physics based code from above. Something just wasn't sitting right with me. I believe the invisible mesh I was using as a wall was causing issues, so I made a new cylinder to replace it, ans so far, it's better.
At them moment, when the players change sides, the camera moves to keep them in view. I'm wondering if it'll be necessary to set up code for the characters to be on opposite sides of the screen from their starting positions.
I don't have jumps at the moment, so to experiment, I flipped the camera to the other side of the players in code. Now the input directions are reversed, and the players don't strafe in the right directions.
In vanilla UFE, the mirror variable seems to handle this. The mirror is flipped based on the players positions relative to each other, but I think for z-axis
Does anyone know a way to flip the mirror variable based on which side of the screen the player is on?
As it stands, the code is very messy, but functional. I am now waiting until v1.1 to go tidy it up and test, as I don't know what breaking changes might happen.
Once that's done, I'll share what I have, and hopefully the community here can help tidy and integrate it better, as there may be redundancy or conflict with existing UFE stuff.
Current implemented functions:
Character movement - forward/back/strafe
Character attack directions - characters can differentiate between being attacked form the front, rear or each side
Character physics - the knockback had to be changed so that they don't just move in a 2d plane, but correctly away from heir attacker
Camera - rotates and follows midpoint
Camera aligns to face nearest side, so it doesn't rotate too much when characters swap sides
Camera bounds - the camera had to be limited so it doesn't pass through the outer walls/objects that make up the stage.
I've discovered an error with my implementation.
moves with directional input, ie: back and kick - don't change axis properly.
Once you circle around your opponent, the directional input gets flipped, rather than staying constant.
I had a similar issue with basic movement, I think it's a lot ot do with UFE's 2d axis setting.
Ill have a hunt through the code, see where direction is used in attacks, and fix it.
Have you looked at ControlsScript, testCharacterRotation()? Looking at that function, UFE uses world position in x to decided which way to set the mirror value.
I replaced that with a custom one a while back.
It was the
inputRef.engineRelatedButton = axis == 1 ? ButtonPress.Back : ButtonPress.Foward;
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
Causing the issue. My movement code is experimental, so I had left that mostly untouched below it.
I altered that to
{
if (camRight || camFront)
{
inputRef.engineRelatedButton = ButtonPress.Foward;
}
else if (camLeft || camRear)
{
inputRef.engineRelatedButton = ButtonPress.Back;
}
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
if (inputController.GetAxisRaw(inputRef) < 0)
{
if (camRight || camFront)
{
inputRef.engineRelatedButton = ButtonPress.Back;
}
else if (camLeft || camRear)
{
inputRef.engineRelatedButton = ButtonPress.Foward;
}
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
Using some variables from my extended code.
Adding the extra axis really complicated things
It seems ok now, though I may have to do something similar with the vertical axis, but as I mention above, this code is in need of a lot of tidying anyway, so I'm just glad I have functionality until 1.1 is released.
I'm hoping 3dArena gets voted in next, I'll keep working regardless though.
At least with the basics covered, I can test gameplay, that way my assets should be fine, even if the later version of UFE makes my code redundant.
I'll share that with the release of 1.1, so others can have a stop-gap solution too.
Ok, Im ready to start sharing what I did.
A few caveats:
I won't be posting the entirety of the classes, because UFE is not open source.
This is an implementation, it's nowhere near perfect, so feel free to change anything you don't like, and even share it back if you want to. (no obligation there).
I'll post changes class by class, each one getting it's own post so we can hopefully keep things neat in here.
First class changed is CameraScript
//New variables added
private Rigidbody _rigidbody;
public Transform P1Trans;
public Transform P2Trans;
public float distScale = 1.0f;
private Vector3 Perpendicular = Vector3.zero;
private Vector3 midPoint = Vector3.zero;
//removed the two ground height variables
void Start()
{
removed "standard distance" line, no other changes here
}
//I commented out all of this see LateUpdate below
/*void FixedUpdate(){}*/
//new method
void awake()
{
_rigidbody = Camera.main.transform.rigidbody;
//camera uses rigid body physics to collide with outer arena walls
}
//used instead of fixed update
void LateUpdate()
{
//modified version of FixedUpdate, with these changes
if()
{
//use the same code from FixedUpdate
}else{
Vector3 target = (P1Trans.position - P2Trans.position);
Perpendicular = Vector3.Cross(target, Vector3.up);
midPoint = (P1Trans.position + P2Trans.position) * 0.5f;
if (UFE.config.cameraOptions.followJumpingCharacter)
midPoint.y += UFE.config.cameraOptions.initialDistance.y;
float dist = Vector3.Distance(P1Trans.position, P2Trans.position) * distScale;
dist = Mathf.Clamp(dist, UFE.config.cameraOptions.minZoom, UFE.config.cameraOptions.maxZoom);
Camera.main.fieldOfView = Mathf.Lerp(Camera.main.fieldOfView, UFE.config.cameraOptions.initialFieldOfView, Time.deltaTime * UFE.config.cameraOptions.smooth);
Vector3 desiredPos = midPoint + Perpendicular.normalized * dist - _rigidbody.position;
Vector3 invertPos = midPoint - Perpendicular.normalized * dist - _rigidbody.position;
float desiredDist = Vector3.Distance(_rigidbody.position, desiredPos);
float invertDist = Vector3.Distance(_rigidbody.position, invertPos);
if (desiredDist < invertDist)
{
if (_rigidbody.position != desiredPos)
{
_rigidbody.velocity = desiredPos * UFE.config.cameraOptions.smooth;
}
}
else if (desiredDist > invertDist)
{
if (_rigidbody.position != invertPos)
{
_rigidbody.velocity = invertPos * UFE.config.cameraOptions.smooth;
}
}
else
{
_rigidbody.velocity = Vector3.Lerp(_rigidbody.velocity, Vector3.zero, Time.deltaTime * UFE.config.cameraOptions.smooth);
}
Camera.main.transform.rotation = Quaternion.Slerp(Camera.main.transform.rotation, Quaternion.LookRotation(midPoint - Camera.main.transform.position), UFE.config.cameraOptions.smooth);
}
}
///everything else in this class remains the same as stock UFE version
CharacterInfo is a minor change,
add this variable
//myaddition
public float moveSideSpeed = 3.8f; // How fast this character can move sideways
ControlsScipt
//my addition for controlling speed of rot
private float rotationSpeed;
//my bools for testing character alignment
public bool pFront, pRear, pLeft, pRight;
//my bools for testing camera alignment
public bool camFront, camRear, camLeft, camRight;
//my additions
Vector3 newMoveDirection;
float h;
float v;
int axis;
private int moveDir;
// for ring bounds
Vector3 stageCentre = Vector3.zero;
float radius = UFE.config.selectedStage.ringRadius;
void Start()
{
//there's a script that controls what the camera points at, add this in for that
if (gameObject.name == "Player1")
{
CamPointScript p1point = character.GetComponentInChildren<CamPointScript>();
cameraScript.P1Trans = p1point.childEmpty;
}
if (gameObject.name == "Player2")
{
CamPointScript p2point = character.GetComponentInChildren<CamPointScript>();
cameraScript.P2Trans = p2point.childEmpty;
}
}
private void testCharacterRotation(float rotationSpeed, bool forceMirror)
{
}
//new method, this rotates the player on certain conditions. it's called later
private void Rotating()
{
bool smooth = true;
Transform _myTransform = character.transform;
var playerLook = new Vector3(opponent.transform.position.x, character.transform.position.y, opponent.transform.position.z);
character.transform.LookAt(playerLook);
}
//two more new methods, again,the code is experimental, hence the roughness, and redundancy here
//this method checks which side of the player the opponent is on
private void TestPlayerAlignment()
{
Vector3 forward = character.transform.TransformDirection(Vector3.forward);
Vector3 sides = character.transform.TransformDirection(Vector3.left);
Vector3 n = character.transform.TransformDirection(Vector3.up);
Vector3 toOther = opponent.transform.position - character.transform.position;
// Vector3 heading = new Vector3(Vector3.Dot(sides, toOther), 0, Vector3.Dot(forward, toOther));
// angle in [0,180]
float angle = Vector3.Angle(forward, toOther);
float sign = Mathf.Sign(Vector3.Dot(n, Vector3.Cross(forward, toOther)));
// angle in [-179,180]
float signed_angle = angle * sign;
// angle in [0,360]
float angle360 = ((signed_angle) + 360) % 360;
// print(angle360);
if (angle360 > 315 || angle360 < 45)
{
pFront = true;
}
else { pFront = false; }
if (angle360 < 225 && angle360 > 135)
{
pRear = true;
}
else { pRear = false; }
if (angle360 > 225 && angle360 < 315)
{
pLeft = true;
}
else { pLeft = false; }
if (angle360 < 135 && angle360 > 45)
{
pRight = true;
}
else { pRight = false; }
}
//this method checks which side of the player the camera is on
private void TestCameraAlignment()
{
Vector3 forward = character.transform.TransformDirection(Vector3.forward);
Vector3 sides = character.transform.TransformDirection(Vector3.left);
Vector3 n = character.transform.TransformDirection(Vector3.up);
Vector3 toOther = Camera.main.transform.position - character.transform.position;
// Vector3 heading = new Vector3(Vector3.Dot(sides, toOther), 0, Vector3.Dot(forward, toOther));
// angle in [0,180]
float angle = Vector3.Angle(forward, toOther);
float sign = Mathf.Sign(Vector3.Dot(n, Vector3.Cross(forward, toOther)));
// angle in [-179,180]
float signed_angle = angle * sign;
// angle in [0,360]
float angle360 = ((signed_angle) + 360) % 360;
// print(angle360);
if (angle360 > 315 || angle360 < 45)
{
camFront = true;
}
else { camFront = false; }
if (angle360 < 225 && angle360 > 135)
{
camRear = true;
}
else { camRear = false; }
if (angle360 > 225 && angle360 < 315)
{
camLeft = true;
}
else { camLeft = false; }
if (angle360 < 135 && angle360 > 45)
{
camRight = true;
}
else { camRight = false; }
}
private void validateRotation()
{
//my addition, this means the character will turn to face the opponent only when the following is true
//the idea behind this is to allow you to flank an opponent, and land attack to the side or rear, without the opponent constantly facing you head on
if (myPhysicsScript.IsGrounded() || myPhysicsScript.freeze || currentMove != null) Rotating();
}
void Update()
{
//this is for the experimental z-axis movement
//moveDir variable is used to set speed and animation in PhysicsScript class
// Movement
if (inputRef.inputType == InputType.HorizontalAxis)
{
h = inputController.GetAxisRaw(inputRef);
if (h != 0)
{
axis = 1;
}
}
if (inputRef.inputType == InputType.VerticalAxis)
{
v = inputController.GetAxisRaw(inputRef);
if (v != 0)
{
axis = 2;
}
}
if (h == 0 && v == 0) { axis = 0; moveDir = 0; }
Vector3 q = Vector3.zero;
Vector3 d = Vector3.zero;
TestCameraAlignment();
if (camRight || camFront)
{
if (v > 0.0) { d = character.transform.TransformDirection(Vector3.right); moveDir = 4; }
if (v < 0.0) { d = character.transform.TransformDirection(Vector3.left); moveDir = 3; }
if (v != 0.0 || h != 0.0)
{
if (h > 0.0) { q = character.transform.TransformDirection(Vector3.forward); moveDir = 1; }
if (h < 0.0) { q = character.transform.TransformDirection(Vector3.back); moveDir = 2; }
}
}
else if (camLeft || camRear)
{
if (v > 0.0) { d = character.transform.TransformDirection(Vector3.left); moveDir = 3; }
if (v < 0.0) { d = character.transform.TransformDirection(Vector3.right); moveDir = 4; }
if (v != 0.0 || h != 0.0)
{
if (h < 0.0) { q = character.transform.TransformDirection(Vector3.forward); moveDir = 1; }
if (h > 0.0) { q = character.transform.TransformDirection(Vector3.back); moveDir = 2; }
}
}
newMoveDirection = (q + d);
if (currentMove == null)
{
myPhysicsScript.newMove(moveDir, newMoveDirection, axis);
}
//camera alignment is used in the following code to keep the input consistent regardless of orientation
if (inputRef.inputType != InputType.Button && inputController.GetAxisRaw(inputRef) != 0)
{
if (inputRef.inputType == InputType.HorizontalAxis)
{
if (inputController.GetAxisRaw(inputRef) > 0)
{
if (camRight || camFront)
{
inputRef.engineRelatedButton = ButtonPress.Foward;
}
else if (camLeft || camRear)
{
inputRef.engineRelatedButton = ButtonPress.Back;
}
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
if (inputController.GetAxisRaw(inputRef) < 0)
{
if (camRight || camFront)
{
inputRef.engineRelatedButton = ButtonPress.Back;
}
else if (camLeft || camRear)
{
inputRef.engineRelatedButton = ButtonPress.Foward;
}
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
// Check for potential blocking
if (inputRef.engineRelatedButton == ButtonPress.Back && UFE.config.blockOptions.blockType == BlockType.HoldBack)
{
potentialBlock = true;
}
// Check for potential parry
if (((inputRef.engineRelatedButton == ButtonPress.Back && UFE.config.blockOptions.parryType == ParryType.TapBack) ||
(inputRef.engineRelatedButton == ButtonPress.Foward && UFE.config.blockOptions.parryType == ParryType.TapForward)) &&
potentialParry == 0 && inputRef.heldDown == 0 && currentMove == null && !isBlocking && !stunned && !blockStunned)
{
potentialParry = UFE.config.blockOptions.parryTiming;
}
}
if (inputRef.inputType == InputType.VerticalAxis)
{
if (inputController.GetAxisRaw(inputRef) > 0)
{
inputRef.engineRelatedButton = ButtonPress.Down;
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
if (inputController.GetAxisRaw(inputRef) < 0)
{
inputRef.engineRelatedButton = ButtonPress.Up;
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
}
// Check for potential blocking
if (inputRef.engineRelatedButton == ButtonPress.Back && UFE.config.blockOptions.blockType == BlockType.HoldBack)
{
potentialBlock = true;
}
// Check for potential parry
if (((inputRef.engineRelatedButton == ButtonPress.Back && UFE.config.blockOptions.parryType == ParryType.TapBack) ||
(inputRef.engineRelatedButton == ButtonPress.Foward && UFE.config.blockOptions.parryType == ParryType.TapForward)) &&
potentialParry == 0 && inputRef.heldDown == 0 && currentMove == null && !isBlocking && !stunned && !blockStunned)
{
potentialParry = UFE.config.blockOptions.parryTiming;
}
//jump 'n' crouch
if (inputController.GetAxisRaw(inputRef) > 0)
{
inputRef.engineRelatedButton = ButtonPress.Up;
if (inputRef.heldDown == 0)
{
if (!myPhysicsScript.IsGrounded() && myInfo.physics.multiJumps > 1)
myPhysicsScript.Jump();
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
}
if (currentMove == null && currentState == PossibleStates.Stand && isBlocking && !stunned && !blockStunned)
{
myPhysicsScript.isTakingOff = true;
float delayTime = (float)myInfo.physics.jumpDelay / UFE.config.fps;
if (myMoveSetScript.AnimationExists(myMoveSetScript.basicMoves.takeOff.name))
{
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.takeOff);
myMoveSetScript.SetAnimationSpeed(myMoveSetScript.basicMoves.takeOff.name,
myMoveSetScript.GetAnimationLengh(myMoveSetScript.basicMoves.takeOff.name) / delayTime);
}
myPhysicsScript.Invoke("Jump", delayTime);
//myPhysicsScript.jump();
return;
}
if (myPhysicsScript.isTakingOff) return;
inputRef.heldDown += Time.deltaTime;
}
else if (inputController.GetAxisRaw(inputRef) < 0)
{
inputRef.engineRelatedButton = ButtonPress.Down;
if (inputRef.heldDown == 0 && testMoveExecution(inputRef.engineRelatedButton, false)) return;
inputRef.heldDown += Time.deltaTime;
if (myPhysicsScript.IsGrounded() && currentMove == null && isBlocking && !stunned && !blockStunned)
{
currentState = PossibleStates.Crouch;
if (!myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.crouching.name))
{
if (!isBlocking && !myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.crouching.name))
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.crouching);
if (isBlocking && !myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.blockingCrouchingPose.name))
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.blockingCrouchingPose);
}
}
}
}
foreach (InputReferences inputRef2 in inputController.inputReferences)
{
if (inputRef2.inputType == InputType.Button && inputController.GetButtonDown(inputRef2))
{
storedMove = myMoveSetScript.GetMove(
new ButtonPress[] { inputRef.engineRelatedButton, inputRef2.engineRelatedButton }, 0, currentMove, false, true);
if ((currentMove == null || currentMove.cancelable) && storedMove != null)
{
currentMove = storedMove;
storedMove = null;
return;
}
}
}
}
}
HitBoxes Script
Public class HitBox
{
//my addition vector2 - vector3
public Vector3 offSet;
//my addition we need this to align the hitboxes
public float offSetZ;
}
System.Serializable]
public class HurtBox {
//my addition vector2 - vector3
public Vector3 offSet;
[HideInInspector] public Vector3 position;
}
[System.Serializable]
public class BlockArea {
//my addition vector2 - vector3
public Vector3 offSet;
[HideInInspector] public Vector3 position;
}
public Vector3 testCollision(BlockArea blockableArea)
{
//comment these lines out so detect3d is always on, if not, enable it in the editor
/* if (!detect3dHits)
{
blockablePosition.z = -1;
hitBoxPosition.z = -1;
}*/
}
public Vector3 testCollision(HurtBox[] hurtBoxes)
{
//changed to always detect 3d
/* if (!detect3dHits)
{
hurtBoxPosition.z = -1;
hitBoxPosition.z = -1;
}*/
}
public bool testCollision(Vector3 projectilePos, float projectileRadius)
{
//changed to always detect 3d
/* if (!detect3dHits)
{
hitBoxPosition = new Vector3(hitBox.position.position.x, hitBox.position.position.y, 0);
projectilePos = new Vector3(projectilePos.x, projectilePos.y, 0);
}*/
}
public float testCollision(HitBox[] opHitBoxes)
{
//changed to always detect 3d
/* if (!detect3dHits)
{
opHitBoxPosition = new Vector3(opHitBox.position.position.x, opHitBox.position.position.y, 0);
hitBoxPosition = new Vector3(hitBox.position.position.x, hitBox.position.position.y, 0);
}*/
}
void OnDrawGizmos()
{
//there are several instances of this line, remove them all if you want detect3d automatic
// if (!detect3dHits) hitBoxPosition.z = -1;
}
MoveInfo
// swings added to allow char to be knocked sideways leave other values unchanged
public enum HitType {
SwingFromLeft,
SwingFromRight
}
//my addition
public enum HitDirection
{
Front,
Side,
Rear
}
[System.Serializable]
public class AppliedForce
{
//add this line
public bool resetPreviousZAxis;
//change this from Vector2
public Vector3 force;
[HideInInspector]
public bool casted;
}
Also, these changes
public class Hit
{
//my addition
public HitDirection hitDirection;
public bool resetPreviousZAxisPush;
public Vector3 pushForce;
public bool resetPreviousZAxis;
public Vector3 appliedForce;
}
MoveSetScript
public class BasicMoves {
//my additions, these are the z-axis moves
public BasicMoveInfo moveLeft = new BasicMoveInfo();
public BasicMoveInfo moveRight = new BasicMoveInfo();
//and the reactions from being hit side-on
public BasicMoveInfo getHitFromLeft = new BasicMoveInfo();
public BasicMoveInfo getHitFromRight = new BasicMoveInfo();
}
private void fillMoves(){
//my additions
setBasicMoveAnimation(basicMoves.moveLeft, "moveLeft", WrapMode.Loop);
setBasicMoveAnimation(basicMoves.moveRight, "moveRight", WrapMode.Loop);
setBasicMoveAnimation(basicMoves.getHitFromLeft, "getHitFromLeft", WrapMode.ClampForever);
setBasicMoveAnimation(basicMoves.getHitFromRight, "getHitFromRight", WrapMode.ClampForever);
}
And the last one: PhysicsScript
public class PhysicsScript : MonoBehaviour
{
//change from float to Vector3
private Vector3 moveDirection;
//added for z-axis movement
private float zAxisForce = 0;
//my additions
float speed;
int movementAnim = 0;
Vector3 stageCentre = Vector3.zero;
float radius = UFE.config.selectedStage.ringRadius;
//I replaced this with a different method
/* public void Move(){}*/
//This one ;)
public void newMove(int moveDir, Vector3 newMoveDirection, int axis)
{
if (!IsGrounded()) return;
if (axis == 1)
{
if (moveDir == 1)
{
speed = myControlsScript.myInfo.physics.moveForwardSpeed;
movementAnim = 1;
}
if (moveDir == 2)
{
speed = myControlsScript.myInfo.physics.moveBackSpeed;
movementAnim = 2;
}
}
if (axis == 2)
{
if (moveDir == 3)
{
speed = myControlsScript.myInfo.physics.moveSideSpeed;
movementAnim = 3;
} if (moveDir == 4)
{
speed = myControlsScript.myInfo.physics.moveSideSpeed;
movementAnim = 4;
}
}
if (axis == 0)
{
if (moveDir == 0)
{
movementAnim = 0;
}
}
//this bit was for testing
/* if (gameObject.name == "Player1")
{
Debug.Log(movementAnim);
}*/
moveDirection = newMoveDirection;
}
public bool IsMoving()
{
//moveDirection is no longer a float, so value for each vector axis added
return (moveDirection.x != 0 && moveDirection.y != 0 && moveDirection.z != 0);
}
//added float for z forces
public void ResetForces(bool resetZ)
{
if (resetZ) zAxisForce = 0;
}
public void AddForce(Vector3 push, int mirror)
{
if (!myControlsScript.myInfo.physics.cumulativeForce)
{
//my addition
zAxisForce = 0;
}
if (verticalForce < 0 && push.y > 0 && UFE.config.comboOptions.resetFallingForceOnHit) verticalForce = 0;
zAxisForce -= push.z;
}
public void ApplyForces(MoveInfo move)
{
//updated for z movement
float appliedFriction = (moveDirection.x != 0 && moveDirection.y != 0 && moveDirection.z != 0 || myControlsScript.myInfo.physics.highMovingFriction) ?
UFE.config.selectedStage.groundFriction : myControlsScript.myInfo.physics.friction;
else
{
//this is the bulk of the z-axis code
if (!IsGrounded())
{
zAxisForce = 0;
appliedFriction = 0;
if (verticalForce == 0) verticalForce = -.1f;
}
if (horizontalForce != 0 && !isTakingOff
|| zAxisForce != 0 && !isTakingOff)
{
if (horizontalForce > 0)
{
horizontalForce -= appliedFriction * Time.deltaTime;
horizontalForce = Mathf.Max(0, horizontalForce);
}
else if (horizontalForce < 0)
{
horizontalForce += appliedFriction * Time.deltaTime;
horizontalForce = Mathf.Min(0, horizontalForce);
}
if (zAxisForce > 0)
{
zAxisForce -= appliedFriction * Time.deltaTime;
zAxisForce = Mathf.Max(0, zAxisForce);
}
else if (zAxisForce < 0)
{
zAxisForce += appliedFriction * Time.deltaTime;
zAxisForce = Mathf.Min(0, zAxisForce);
}
Vector3 q = Vector3.zero;
Vector3 d = Vector3.zero;
if (myControlsScript.camRight || myControlsScript.camFront)
{
d = character.transform.TransformDirection(Vector3.right) * -zAxisForce * Time.deltaTime;
}
else if (myControlsScript.camLeft || myControlsScript.camRear)
{
d = character.transform.TransformDirection(Vector3.right) * zAxisForce * Time.deltaTime;
}
Vector3 finalMove = (q + d);
transform.Translate(finalMove);
if (!isTakingOff)
{
transform.Translate(moveDirection * speed * Time.deltaTime);
}
//modified
float dst = Vector3.Distance(stageCentre, transform.position);
if (dst > radius)
{
Vector3 vect = stageCentre - transform.position;
vect = vect.normalized;
vect *= (dst - radius);
transform.position += vect;
}
if (myControlsScript.currentState == PossibleStates.Down) return;
if (IsGrounded() && myControlsScript.currentState != PossibleStates.Down)
{
else if (myControlsScript.currentState != PossibleStates.Stand)
{
if ((myControlsScript.currentMove != null && myControlsScript.currentMove.cancelMoveWheLanding) ||
myControlsScript.currentMove == null)
{
airAnimation = myMoveSetScript.basicMoves.landing;
moveDirection.x = 0;
//add this
moveDirection.z = 0;
myControlsScript.KillCurrentMove();
}
if (myControlsScript.currentState != PossibleStates.Crouch) myControlsScript.currentState = PossibleStates.Stand;
}
}
if (!myControlsScript.stunned && !myControlsScript.isBlocking && !myControlsScript.blockStunned &&
move == null && !isTakingOff && myControlsScript.currentState == PossibleStates.Stand)
{
//we check what animation we need elsewhere
if (movementAnim == 1)
{
if (myMoveSetScript.basicMoves.moveForward.clip1 == null)
Debug.LogError("Move Forward animation not found! Make sure you have it set on Character -> Basic Moves -> Move Forward");
if (!myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.moveForward.name, 0f))
{
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.moveForward);
}
}
if (movementAnim == 2)
{
if (myMoveSetScript.basicMoves.moveBack.clip1 == null)
Debug.LogError("Move Back animation not found! Make sure you have it set on Character -> Basic Moves -> Move Back");
if (!myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.moveBack.name, 0f))
{
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.moveBack);
}
}
if (movementAnim == 3)
{
if (myMoveSetScript.basicMoves.moveLeft.clip1 == null)
Debug.LogError("Move Back animation not found! Make sure you have it set on Character -> Basic Moves -> Move Left");
if (!myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.moveLeft.name, 0f))
{
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.moveLeft);
}
}
if (movementAnim == 4)
{
if (myMoveSetScript.basicMoves.moveRight.clip1 == null)
Debug.LogError("Move Back animation not found! Make sure you have it set on Character -> Basic Moves -> Move Right");
if (!myMoveSetScript.IsAnimationPlaying(myMoveSetScript.basicMoves.moveRight.name, 0f))
{
myMoveSetScript.PlayBasicMove(myMoveSetScript.basicMoves.moveRight);
}
}
}
}
//updated for z-axis
if (horizontalForce == 0 && verticalForce == 0 && zAxisForce == 0)
{
moveDirection.x = 0;
moveDirection.y = 0;
moveDirection.z = 0;
}
}
}
I missed this one, sorry.
Class GlobalInfo.
Add this to the stage options
public float ringRadius = 38;
and comment out the existing boundary code. In a 3d environment, we need more than left/right walls
It looks like this code isn't compatible with v1.5
I'll work on fixing that, but if anyone wants to use it, be aware of that.
It looks like this code isn't compatible with v1.5
I'll work on fixing that, but if anyone wants to use it, be aware of that.
Have you had any luck getting this to work?
I'm planning to sit down and have a play with this soon.
Thanks.
Yes, it's going rather well.
I think I have everything working again with the new version. I've been working on animations, so that's why I haven't been on the forum in a while.
The breaking changes for 1.5 aren't all that bad, so you might well be able to fix it yourself.
I'll try to get around to posting the updated code myself. I took a tip from the lads here and started using source control, so hopefully, posting the relevant code won't be so awkward this time.
@steviebops hey, I am creating a game using UFE but wanted to have it the way you are making the cameras and allowing Z-axis movement. Have you made any progress with this and are you willing to share this? I want my game to be similar to EF-12. Can you email me at svwillia@oakland.edu
Hey Steviebops do you think you would be able to look into a Naruto Ultimate Ninja Storm style gameplay? I already know that would require some work even when UFE supports 3d Arenas. I say the Naruto Ninja Storm gameplay is far more interesting and unique than games like Soul Calibur and Tekken. One of my complaints about 3d fighting games has always been the cheap annoying ring outs. Think about it now guys how in god's name can a demon like Nightmare die just by falling in a freaking pool of water in a garden in Soul Calibur 4? lol
haha true! I'm working on a game of my own, so I won't be switching styles at this late stage. I never actually implemented ring outs, as I didn't like them either.
Im going to start sharing the v1.5 code (the latest one I have) here now.
Earlier caveats about testing and optimisation apply, but you'll at least have everything I have.
PhysicsScript.cs
PhysicsScript.cs
[HideInInspector] public bool isTakingOff;
[HideInInspector] public int currentAirJumps;
private Vector3 modMoveDirection;
private float horizontalForce = 0;
//added for z-axis movement
private float zAxisForce = 0;
private float appliedGravity;
//my additions
float speed;
int movementAnim = 0;
Vector3 stageCentre = Vector3.zero;
float radius = UFE.config.selectedStage.ringRadius;
//I use 2 methods, one fo r horizontal, one for vertical, as they haven't been tidied yet.
public void Move(int mirror, float direction)
{
if (!IsGrounded()) return;
if (freeze) return;
if (isTakingOff) return;
moveDirection = direction;
if (mirror == 1)
{
myControlsScript.currentSubState = SubStates.MovingForward;
myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveForwardSpeed * direction;
}
else
{
myControlsScript.currentSubState = SubStates.MovingBack;
myControlsScript.horizontalForce = horizontalForce = myControlsScript.myInfo.physics.moveBackSpeed * direction;
}
}
public void myMove(int mirror, float direction)
{
if (!IsGrounded()) return;
if (freeze) return;
if (isTakingOff) return;
moveDirection = direction;
if (mirror == 1)
{
myControlsScript.currentSubState = SubStates.MovingLeft;
myControlsScript.zAxisForce = zAxisForce = myControlsScript.myInfo.physics.moveSideSpeed * direction;
}
else
{
myControlsScript.currentSubState = SubStates.MovingRight;
myControlsScript.zAxisForce = zAxisForce = myControlsScript.myInfo.physics.moveSideSpeed * direction;
}
}
public void AddForce(Vector3 push, int mirror)
{
push.x *= mirror;
isBouncing = false;
if (!myControlsScript.myInfo.physics.cumulativeForce)
{
//my addition
zAxisForce = 0;
}
zAxisForce += push.z;
}
public void ApplyForces(MoveInfo move)
{
//modified
float dst = Vector3.Distance(stageCentre, transform.position);
if (dst > radius)
{
Vector3 vect = stageCentre - transform.position;
vect = vect.normalized;
vect *= (dst - radius);
transform.position += vect;
}
//updated for z-axis
if (horizontalForce == 0 && verticalForce == 0 && zAxisForce == 0)
{
moveDirection = 0;
}
}
public void ResetForces(bool resetX, bool resetY, bool resetZ)
{
if (resetX) horizontalForce = 0;
if (resetY) verticalForce = 0;
if (resetZ) zAxisForce = 0;
}
Universal Fighting Engine Forum → UFE 1 Source (Deprecated) → Z - axis movement
Powered by PunBB, supported by Informer Technologies, Inc.