i wanna build a Jumppad in my Unity Platformer game (2D).
I thought it will be easy if i just add a Addforceor velocity if my player collides with the jumppad, but there is a problem.
instead of flying in a 45° angle, my pleyer first gets pushed all the way in the direction of the X-Axis, and after in the direction of the Y-Axis.
the bool sprungFlächeBerührt gets true if the player collides with the Jumppad
if(SprungFläche.sprungFlächeBerührt)
{
rb.velocity = new Vector2(10f, 10f);
SprungFläche.sprungFlächeBerührt = false;
}
Quite strange. Might be a bug. Try this:
rb.velocity = new Vector3(10f, 10f, 0f);
Related
I'm currently trying to create a multiplayer game using mirror!
So far I've been successful in creating a lobby and set up a simple character model with a player locomotion script I've taken and learnt inside out from Sebastian Graves on YouTube (you may know him as the dark souls III tutorial guy)
This player locomotion script uses unity's package 'Input System' and is also dependent on using the camera's .forward and .right directions to determine where the player moves and rotates instead of using forces on the rigidbody. This means you actually need the camera free in the scene and unparented from the player.
Here is my HandleRotation() function for rotating my character (not the camera's rotation function):
private void HandleRotation()
{
// target direction is the way we want our player to rotate and move // setting it to 0
Vector3 targetDirection = Vector3.zero;
targetDirection = cameraManager.cameraTransform.forward * inputHandler.verticalInput;
targetDirection += cameraManager.cameraTransform.right * inputHandler.horizontalInput;
targetDirection.Normalize();
targetDirection.y = 0;
if (targetDirection == Vector3.zero)
{
// keep our rotation facing the way we stopped
targetDirection = transform.forward;
}
// Quaternion's are used to calculate rotations
// Look towards our target direction
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
// Slerp = rotation between current rotation and target rotation by the speed you want to rotate * constant time regardless of framerates
Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
transform.rotation = playerRotation;
}
It's also worth mentioning I'm not using cinemachine however I'm open to learning cinemachine as it may be beneficial in the future.
However, from what I've learnt and managed to find about mirror is that you have to parent the Main Camera under your player object's prefab so that when multiple people load in, multiple camera's are created. This has to happen on a Start() function or similar like OnStartLocalPlayer().
public override void OnStartLocalPlayer()
{
if (mainCam != null)
{
// configure and make camera a child of player
mainCam.orthographic = false;
mainCam.transform.SetParent(cameraPivotTransform);
mainCam.transform.localPosition = new Vector3(0f, 0f, -3f);
mainCam.transform.localEulerAngles = new Vector3(0f, 0f, 0f);
cameraTransform = GetComponentInChildren<Camera>().transform;
defaultPosition = cameraTransform.localPosition.z;
}
}
But of course, that means that the camera is no longer independent to the player and so what ends up happening is the camera rotates when the player rotates.
E.g. if I'm in game and looking to the right of my player model and then press 'w' to walk in the direction the camera is facing, my camera will spin with the player keeping the same rotation while my player spins in order to try and walk in the direction the camera is facing.
What my question here would be: Is there a way to create a system using mirror that doesn't require the camera to be parented to the player object prefab on start, and INSTEAD works by keeping it independent in the scene?
(I understand that using forces on a rigidbody is another method of creating a player locomotion script however I would like to avoid that if possible)
If anybody can help that would be greatly appreciated, Thank You! =]
With the constraint of your camera being attached to the player you will have to adapt the camera logic. What you can do is instantiate a proxy transform for the camera and copy that transforms properties to your camera, globally, every frame. The parent constraint component might do this for you. Then do all your transformations on that proxy.
Camera script with instantiation:
Transform proxy;
void Start(){
proxy = (new GameObject()).transform;
}
void Update(){
//transformations on proxy
transform.position = proxy.position;
transform.rotation = proxy.rotation;
}
I'm trying to do a little game on mobile using Unity and I've got a problem with the rotation of a maze.
To add context :
When your moving your finger on the screen, the maze is rotating on himself. There is a ball in it and you need to make it go on a cell to win the level.
When the maze is rotating too fast, the ball falls down and go through the ground and I don't know how to fix it.
I tried to play with the gravity, colliders...
This is the same when the ball is jumping (when the maze is going up and down quickly).
For the moment I just reset the ball position when you're falling.
{
ball.transform.position = new Vector3(0, 2, 0);
maze.transform.position = Vector3.zero;
maze.transform.rotation = Quaternion.identity;
}
Do you guys have some ideas ? Thanks
I had a similar problem in a tilt maze mini-game I worked on. Ideally implementing jkimishere's solution will work but I assume the maze is moving too fast for the collisions to register properly. You'll need to smooth the maze's rotation with a Lerp. In our case we had pressure plates with a tilt value, so it doesn't directly translate to your mobile use but perhaps give you a nudge in the right direction. We used:
public GameObject maze;
private float _lerpTime;
private bool _isRotating;
private Quaternion _startingRot, _desiredRot;
private void Awake()
{
_startingRot = maze.transform.localRotation;
}
private void Update()
{
//Don't want to move the maze if we don't ask for it
if(!_isRotating)
return;
//Lerp the maze's rotation
_lerpTime = Mathf.Clamp(_lerpTime + Time.deltaTime * 0.5f, 0f, 1f);
maze.transform.localRotation = Quaternion.Lerp(_startingRot, _desiredRot, _lerpTime);
//Once the maze gets where it needs to be, stop moving it
if(affectedObject.transform.localRotation.Equals(_desiredRot)
_isRotating = false;
}
private void ActivateTilt()
{
//Set the new starting point of the rotation.
_startingRot = maze.transform.localRotation;
//However you want to calculate the desired rotation here
//Reset our lerp and start rotating again
_lerpTime = 0f;
_isRotating = true;
}
This will ease the rotation of your maze over time. So that the ball can adapt to the new collider positions.
In the rigidbody(for the ball), make the collision detection to continuous, and in the rigidbody for the maze(if you have one) set the collision detection to continuous dynamic. Hope this helps!
I think that is unavoidable if you allow the player to move the platform freely. I suggest you restrain the speed at wich the player can tilt the platform. This way, the ball will have more frames to adapt to the new slope
My 3d ball was moving continuously in the forward direction so I want to give X-rotation for this plus game player was dragging ball horizontally on the screen so for this horizontal movement, I want to give Z-rotation.
To achieve my desire, the result I have made ball parent and child game objects, where parent game object only contains collider and rigidbody and this will do the actual physical movement.
Another side, child game object only contains mesh renderer, this will do desire rotation.
Following image gives you more idea about my structure:
Ball Parent:
Ball Child:
For giving rotation to ball mesh as like parent physics ball, I have written this code:
public class BallMeshRolling : MonoBehaviour
{
private Vector3 ballLastPosition;
void Start ()
{
ballLastPosition = transform.parent.position;
}
void Update ()
{
//implementation-1
//float speed = Vector3.Distance (transform.parent.position, ballLastPosition) * 30f;
//transform.RotateAround (transform.position, Vector3.right, speed);
//implementation-2
//Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized;
//transform.Rotate (differenceInPosition * 10f);
//implementation-3
Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized * 50f;
Quaternion rotation = Quaternion.LookRotation(differenceInPosition);
transform.rotation = rotation;
ballLastPosition = transform.parent.position;
}
}
But none of the above ways working properly, so I expect some other better suggestions from your side.
EDIT: Overall I am trying to achieve something like this:
Catch up - Ketchapp - Highscore 1274
There is a tutorial series from Unity about rolling and moving a 3d ball that can help you to figure out the basics for your problem. Wish it could help.
Roll-a-ball tutorial in Unity Tutorials
I'm making a 2.5D plataform game and I can't get the rotation of the player right. I just want it to rotate on the X-axis while the player move towards left and right. My movement script is this:
if (isWalking)
{
transform.Rotate(0, facingDir, 0);
isWalking = false;
}
else { }
if (Input.GetKey(KeyCode.Space))
GetComponent<Rigidbody>().velocity = new Vector2(GetComponent<Rigidbody>().velocity.x, jumpHeight);
if (Input.GetKey(KeyCode.A)){
GetComponent<Rigidbody>().velocity = new Vector2(-speedHeight, GetComponent<Rigidbody>().velocity.y);
facingDir = 180;
isWalking = true;
}
if (Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody>().velocity = new Vector2(speedHeight, GetComponent<Rigidbody>().velocity.y);
facingDir = 0 ;
isWalking = true;
}
The best way I could rotate it was by transform.rotate(0,180,0) and (0,0,0), but then it keeps rotating non stop, how can I tell what direction the player is moving on the X-axis so I can transform.rotate properly?
transform.forward
This should give you the direction the player is moving in. You can use
transform.LookAt(target);
to orient the player in a specific direction. The main issue is that you are trying to update the direction in the GetKey function which returns true while the key is held down. This results in the character rotating constantly, you have avoided this by using an additional check. You could use Lookat instead in the following manner:
GetComponent<Rigidbody>().velocity = new Vector2(-speedHeight, GetComponent<Rigidbody>().velocity.y);
transform.LookAt(transform.position+new Vector3(GetComponent<Rigidbody>().velocity.x,0,GetComponent<Rigidbody>().velocity.y));
There are better ways to do this but this should solve your problem.
I am trying to create a isometric game like clash of clans. I created a Terrain and I set my camera position to (0,300,-10) and Rotation to (40,45,0) and Perspective to Orthographic. I am using below code to drag a cube but when i drag the cube at some position cube is not able to visible or only some portion of cube is visible. It seems like position (X,Y,Z) all three are changing using below code. But i want to drag cube just like any top down game like Clash of Clans. Please help me to resolve my issue.
void OnMouseDrag ()
{
Vector3 mousePosition = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, 0);
Vector3 objPosition = Camera.main.ScreenToWorldPoint (mousePosition);
this.target.transform.position = objPosition;
}
You need raycasting to solve it. Try this-
void OnMouseDrag ()
{
RaycastHit hitInfo;
bool hit = Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hitInfo, Mathf.Infinity, 1 << LayerMask.NameToLayer ("ground"));
if(hit){
this.target.transform.position = hitInfo.point;
}
}
You can use your existing ground or surface or on whatever your object will move, change the layer name to ground. Be aware that the ground must have a collider.