Like in previous posts i'm trying to make a game where you land on planets and what not,
for the planet rotation i used a parent "ring" and added a rotating script to it:
void Update()
{
Vector3 rotationfloat = new Vector3(0, 0, 2);
transform.Rotate(rotationfloat * rotateSpeed * Time.deltaTime);
}
Just something like that, rotation is nice and all, but then i have an attractor script that is like a gravitational force,
repel = -1;
if (Vector2.Distance(transform.position, planet.transform.position) <= maxDist && Vector2.Distance(transform.position, planet.transform.position) >= minDist)
{
Vector3 desiredPosition = planet.transform.position;
smoothedPosition = (desiredPosition - transform.position) * -1;
rb.AddForce(smoothedPosition * repel);
smoothedPosition = Vector3.zero;
}
Code like that, but when I try landing my player on the planet it makes the player slide across the planet, I've made it so it has a physics material with high friction, but that doesn't work.
You then land on the bottom of the planet and it pulls you to the planet but bounces you off when you touch it, I've checked the physics material (it has no bounce on it).
Anybody might know what is wrong with it?
If you need any more explanation i will try to give you more
Related
I'm relatively new to coding, having just started about a week ago, and I can't seem to figure out or find anything relating to look relative movement using a third person Cinemachine freelook camera.
What I'm trying to accomplish is a camera similar to Risk of Rain 2, or maybe Smite where you can orbit the player and look at the front of them while they're idle, but once you start moving the player rotates towards the direction the camera is looking, and stays facing that direction no matter how they're moving.
I have a basic scene set up with a Cinemachine freelook camera following a cube, but my problem is whenever I turn the camera then move, my character doesn't rotate and instead starts moving in the direction it's facing instead of where the camera's looking, then only starts rotating if I'm pressing a movement key, so the rotation gets disjointed from where the camera's looking, if that makes sense. I kind of frankensteined some code from Royal Skies' movement tutorial and someone else's rotation tutorial for a top-down game.
This is the code for a script applied to my player character;
public float speed = 4.5f;
public Vector3 deltaMove;
public float turnspeed = 500;
void Update()
{
deltaMove = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")) * speed * Time.deltaTime; //movement code
transform.Translate(deltaMove);
float horizontal = Input.GetAxis("Mouse X");
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D) == true) //if wasd pressed, rotate
{
transform.Rotate(horizontal * turnspeed * Vector3.up * Time.deltaTime, Space.World); //the rotation code
}
}
I'd be willing to do anything to be honest, I've been trying to figure this out for a bit now.
Sorry for the noob question, I am still new to unity.
Currently, I'm creating a 2d game in unity in which I have a game object that should move on the x-axis following the x touch position in a smooth way to create a nice swipe mechanics (taking into account that the object is constantly being influenced by the gravity of the Rigidbody2d).
I already tried doing it with Vector3.MoveTowards(), Rigidbody2D.MovePosition(), and changing the velocity of the Rigidbody2D, but none of those created a smooth movement.
Vector3.MoveTowards():
transform.position = Vector3.MoveTowards(transform.position, new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, transform.position.y, transform.position.z), speed * Time.deltaTime);
Rigidbody2D.MovePosition():
rigidbody2D.MovePosition(new Vector3(Camera.main.ScreenToWorldPoint(Input.mousePosition).x,
transform.position.y, transform.position.z));
Rigidbody2D.velocity
Vector3 mousePositionWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (mousePositionWorld.x < transform.position.x)
{
rigidbody2D.velocity = new Vector2(-speed - -(speed * takeOff),
rigidbody2D.velocity.y)
}
else if (mousePositionWorld.x > transform.position.y)
{
rigidbody2D.velocity = new Vector2(+speed - (speed * takeOff),
rigidbody2D.velocity.y);
}
Am I missing something or is there a better way to achieve this?
I don't know what you mean by smooth, but i think that you can use Lerp function. Here is an example:
https://www.youtube.com/watch?v=d6BPukJ5QkA
is a short video.
I am trying to make a 2d plat-former where you see the player from the side. I want him to be continuously moving and you have to press space at the right time so he doesn't fall. Right now everything works but he doesn't collide with the ground. I want it to be like he's running behind a wall so I want to ignore a certain layer I have made and collide with the boxes below that. So far I have tried ray casting, watched multiple tutorials, and did box collisions. Box collisions worked but to get all the platforms counted as solid I'd need like 50 box colliders. Here is my current code:
public int playerSpeed = 10;
public int playerJumpPower = 1250;
public float moveX;
public float playerYSize = 2;
public LayerMask mainGround;
public float playerFallSpeed = 5;
void Awake(){
}
// Update is called once per frame
void Update()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(10, 0));
if(hit.distance < 0.7f){
print("hi");
}
Vector3 characterTargetPosition = new Vector3(transform.position.x + playerSpeed, transform.position.y, transform.position.z);
transform.position = Vector3.Lerp(transform.position, characterTargetPosition, playerSpeed * Time.deltaTime);
if(Input.GetKeyDown("space")){
// float playerTargetPosY = transform.position.y + playerJumpPower;
// Vector3 characterTargetPosition = new Vector3(transform.position.x, playerTargetPosY, transform.position.z);
// transform.position = Vector3.Lerp(transform.position, characterTargetPosition, playerJumpPower * Time.deltaTime);
gameObject.GetComponent<Rigidbody2D>().AddForce(Vector2.up * playerJumpPower);
}
//PlayerMove();
}
I have a rigidBody2D on my player so right now he just falls through the ground but the jump does work. If there is any easy way to do this. Like some script, a tutorial, or website I'm open for it. Please help.
Do you have a Rigidbody2D in your player? Things that will move usually have to have a RigidBody
(sorry for posting this as an answer. Cant comment yet)
EDIT:
try this:
Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
//Physics usually are done in FixedUpdate to be more constant
public void FixedUpdate(){
if (Input.GetKeyDown("space"))
{
if(!rb.simulated)
//player can fall
rb.simulated = true;
rb.AddForce(Vector2.up * playerJumpPower);
}
else
{
//third argument is the distance from the center of the object where it will collide
//therefore you want the distance from the center to the bottom of the sprite
//which is half of the player height if the center is actually in the center of the sprite
RaycastHit2D hit = Physics2D.Raycast(transform.position, -Vector2.up, playerYSize / 2);
if (hit.collider)
{
//make player stop falling
rb.simulated = false;
}
}
}
If the player is the only thing that will collide with something you can just take out the colliders from the object that the player will not collide with.
Else you can check for the layer of the collided object with hit.collider.gameObject.layer and decide if the player will collide with that layer or not
(note that you have to compare with the index of the layer. If you want to get the index by its name you can use LayerMask.NameToLayer(/*layer name*/))
you will have to do rb.simulated = true everytime you want to do something with the RigidBody (like AddForce())
hope it helped :)
I'm currently working on a school game project where i need to have the player climb walls and pick up stuff. I am currently stuck in figuring out how to make the player rotate perpendicular to where the model's faces are while he/she moves towards a corner of a wall as shown below.
Something like this:
I searched for some methods to achieve this but i haven't found anything concrete so far.
Edit: I tried Reasurria's method and it kinda works.
if (Physics.Raycast (transform.position, -transform.up, out hit) && hit.collider.GetComponent<WallModifier> ()) {
transform.rotation = Quaternion.LookRotation (hit.normal, Vector3.right);
//Physics.gravity = hit.normal * -10.0f;
}
My player does indeed rotate correctly pependicular to the slope/wall but then my camera code completly breaks when trying to actually climb the wall. This shows how it looks like in first person and this shows how it looks like in the scene view.
While very funny, it is not obviously desired to have such effect.
Here is the camera code:
void Update () {
if (Input.GetKeyDown (KeyCode.Escape) || toggle && Input.GetMouseButtonDown (0)) {
toggle = !toggle;
}
if (!toggle && Application.isFocused) {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
var md = new Vector2 (Input.GetAxisRaw ("Mouse X"), Input.GetAxisRaw ("Mouse Y"));
md = Vector2.Scale (md, new Vector2 (sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp (smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp (smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp (mouseLook.y, minClamp, maxClamp);
transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized);
character.transform.localRotation = Quaternion.AngleAxis (mouseLook.x, character.transform.up.normalized);
if (rotateModel && antModel)
antModel.transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, (Vector3.right + transform.right).normalized) * Quaternion.Euler (0, 90, 0);
} else {
Cursor.visible = true;
Cursor.lockState = CursorLockMode.None;
Application.runInBackground = false;
}
}
This code was taken by this person.
Do you mean perpendicular? In other words, rotate along x axis with -90 degree.
transform.Rotate(new Vector3(-90, 0, 0));
If I understand correctly, you may want to use Raycast.normal. So you would raycast from your player position with a direction equal to your player's local Vector3.down (player.transform.up * -1.0f).
You can use Quaternion.LookAt(surfaceNormal) to align your players 'up' vector with the normal of the surface under the player. This may involve some 90 degree offset to make the two 'up' vectors match.
Depending on your goal you may also want to set Physics.gravity to surfaceNormal * -10.0f or implement some custom gravity solution if the new surface will function as ground.
You can add empty GameObject with attached collider, than you can use OnTriggerEnter to rotate your Player. Add flag and on every odd enter rotate in one side and on every even enter rotate to opposite side as shingo said
Example
I'm recreating a movement system from dragon quest heroes rocket slime on the DS. In that game, the player can hold down the A button and stretch their slime main character in a direction. Letting go of A while it's stretched would sling them off in that direction.
Here's a gif of what it looks like:
Notice how he bounces off the walls diagonally. My replication currently looks like this (ignore the buggy animations :P)
It looks good! However, if I were to hit a wall diagonally, I would just move backwards in the opposite direction rather than reflecting off it.
Here's the code for how I handle bouncing off walls.
IEnumerator wallBounce(Vector2 hitVelocity)
{
playerAnimator.enabled = true;
yield return new WaitForSeconds(.3f);
playerAnimator.CrossFade("Walking " + curDirection, 0); // place holder animation
pVelocity = Vector2.Scale(-pVelocity,new Vector2(0.25f,0.25f));
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
curState = state.blasting;
transform.position = Vector3.MoveTowards(transform.position, endPos, 5f * Time.deltaTime);
}
I know about the Vector3.Reflect method in Unity but I'm not really sure how to implement it into my current code.
I seem to have done it.
I get the reflection vector like this:
Vector3 reflectedVelocity = Vector3.Reflect(pVelocity*.5f, foundHit.normal);
And then pass it to wallBounce as the hitVelocity.
StartCoroutine(wallBounce(reflectedVelocity));
I then changed this line:
endPos = transform.position + new Vector3(pVelocity.x, pVelocity.y);
into
endPos = transform.position + hitVelocity;