I'm creating a Vive VR Passive VR experience, where your in a space ship and without any controls, it moves passively through the whole solar system. It's not AI, there will be a predetermined destination.
My question: How to make on object move passively?(A.K.A Space Ship with cameras)
You have a starting point, and a destination point, then Lerp between them. The examle in the unity documentation has a example for your exact question.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Transform startMarker;
public Transform endMarker;
public float speed = 1.0F;
private float startTime;
private float journeyLength;
void Start() {
startTime = Time.time;
journeyLength = Vector3.Distance(startMarker.position, endMarker.position);
}
void Update() {
float distCovered = (Time.time - startTime) * speed;
float fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fracJourney);
}
}
You would attach that script to your "Spaceship" root object, you would then make the player a child of the spaceship so it will move with the ship as it goes along it's route.
Path Magic on the Asset Store could do it all for you, and you probably don't have to code anything.
Related
I am trying to create a minigame similar to the fishing mechanism in Stardew Valley. I have two boundaries which are empty objects positioned at each end of a rectangle to keep the fish and the hook inside of the zone. When I run my script, the fish spawns at the bottom boundary and moves up instead of the position it is initially in. The hook generates at the bottom boundary and doesn't move upon user input.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FishingMiniGame : MonoBehaviour
{
//Make the Egg move
[Header("Fishing Area")]
[SerializeField] Transform topBounds;
[SerializeField] Transform bottomBounds;
[Header("Fish Settings")]
[SerializeField] Transform Fish;
[SerializeField] float smoothMotion = 3f;
[SerializeField] float fishTimeRandomizer = 3f;
float fishPosition;
float fishSpeed;
float fishTimer;
float fishTargetPosition;
[Header("Hook Settinds")]
[SerializeField] Transform Hook;
[SerializeField] float HookSize = .18f;
[SerializeField] float HookSpeed = .1f;
[SerializeField] float HookGravity = .05f;
float hookPosition;
float hookPullVelocity;
private void FixedUpdate()
{
MoveFish();
MoveHook();
}
private void MoveHook()
{
if(Input.GetMouseButtonDown(0))
{
//increase our pull velocity
hookPullVelocity += HookSpeed * Time.deltaTime; //raises out hook
}
hookPullVelocity -= HookGravity * Time.deltaTime;
hookPosition += hookPullVelocity;
hookPosition = Mathf.Clamp(hookPosition, 0, 1); //keep the jook withon bounds
Hook.position = Vector3.Lerp(bottomBounds.position, topBounds.position, hookPosition);
}
private void MoveFish()
{
//based on timer, pick random position
//move fish to that position smoothly
fishTimer -= Time.deltaTime;
if(fishTimer < 0)
{
//pick a new target position
//reset timer
fishTimer = Random.value * fishTimeRandomizer;
fishTargetPosition = Random.value;
}
fishPosition = Mathf.SmoothDamp(fishPosition, fishTargetPosition, ref fishSpeed, smoothMotion);
Fish.position = Vector3.Lerp(bottomBounds, topBounds, fishPosition);
}
}
Well, first, making all the code in one script will be confuse. Try giving that fish its own script and game object.
Plus, take a look into Lerp. I think you are missundertanding how to use it. It takes 3 parameters with a being the original Vector3, so your current hook or fish position, b is your Vector3 target position, and t is the step or timestep. Should be delta or delta*someMultiplier.
What #MickyD said is also true, input should be performed during Update(), but that will not fix you code. Update(), FixedUpdate() and LateUpdate() are kinda the same but they run always in that order: Update -> FixedUpdate -> LateUpdate. So keep that in mind.
By the way, your gravity aplies every frame, so your hook is fighting against it even when you are lifting, resulting in half the force being neutralized. Making the gravity only apply on an else after your input will give you a much clear control of forces.
I am a beginner in Unity developing a 2D top-down mobile game. I am trying to create an enemy movement script that mimics the pattern of the leech enemy below:
This enemy is constantly trying to move towards the player but even though it can move quite quickly, due to its momentum, you are able to kite it as it cannot make a sharp turn without first taking some time to build speed in another direction.
I have created a script for enemies to constantly be targeting the player based on the player's current position but it is too difficult to dodge my enemies as they are able to turn instantly when the player does and maintain a constant speed. I would like to balance them to be more like this leech enemy so the player can dodge them by taking advantage of the enemy's current momentum with proper timing. How can I create this momentum effect for my enemies?
If you're using Unity's physics here's a way to do this nicely:
Walkable.cs
Create a modular component that all walkable game objects will use. The purpose of the component is to keep the object moving in the specified direction while stabilising the forces. It uses the values you configure in the inspector for speed and force. It does the movement inside of FixedUpdate as physics movement require it.
public class Walkable : MonoBehaviour {
private const float ForcePower = 10f;
public new Rigidbody2D rigidbody;
public float speed = 2f;
public float force = 2f;
private Vector2 direction;
public void MoveTo (Vector2 direction) {
this.direction = direction;
}
public void Stop() {
MoveTo(Vector2.zero);
}
private void FixedUpdate() {
var desiredVelocity = direction * speed;
var deltaVelocity = desiredVelocity - rigidbody.velocity;
Vector3 moveForce = deltaVelocity * (force * ForcePower * Time.fixedDeltaTime);
rigidbody.AddForce(moveForce);
}
}
Character.cs
This is a simple example of character that will follow a target. Notice how all it's doing is passing the direction to the walkable from inside an Update function.
public class Character : MonoBehaviour {
public Transform target;
public Walkable walkable;
private void Update() {
var directionTowardsTarget = (target.position - this.transform.position).normalized;
walkable.MoveTo(directionTowardsTarget);
}
}
Configurations
By configuring move and force variables you can get a variety of movement styles, some that can move fast but take a long time to ramp up, some that ramp up fast but move slowly overall.
You can also play around with with mass and linear drag on the Rigidbody2D to get even more control over the movement style.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public float movementSpeed;
public Rigidbody2D Rigidbody;
private Vector2 moveDirection;
public Transform Player;
void Start()
{
}
void Update()
{
ProcessInputs();
} void FixedUpdate()
{
move();
}
void ProcessInputs()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY).normalized;
}
void move()
{
Rigidbody.velocity = new Vector2(moveDirection.x * movementSpeed, moveDirection.y * movementSpeed);
}
}
So i needed some tips so i thoght id ask here, i wanted to implement dashing in my Top-Down-Shooter but i didnt find any code on Youtube that would properly work with my code i have also tried moveing the players position +2 to the wanted direction but i couldnt work it out.
id be happy if yall could help me.
Nice that you are using FixedUpdate() for physics - many beginners use that wrong.
However do not set velocity manually. Use AddForce.
It will effectively set the velocity but automatically takes the objects mass into account and allows to speed up instead of instantly being at speed.
That is the more logical approach since you move in a direction by applying forces to your body.
For Dashing, you could add a significantly higher force for a small number of Physics frames (aka small number of FixedUpdate calls). You can use a countdown which you set to a number when the chaarcter hsould start dashing.
In the FixedUpdate you decrement the counter and as long as it is >0 you apply the dashing force.
I'm working on a spaceflight game in unity and stumbled across this simple logical error. I want to be able to add relative movement to my spaceship, but also for it to keep the momentum in that direction when you turn. I've sot a separate script for looking around and movement. Here is my movement source code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController ship;
public float speed = 0.001f;
float momentum = 0f;
Vector3 velocity;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
momentum = momentum + Input.GetAxis("Vertical");
Vector3 move = transform.forward * momentum * 0.001f;
ship.Move(move);
}
}
I know this is a simple question, my brain is just kind of stuck right now. Thanks! ~OwenPT
Do I understand correctly that you want the spaceship fly forward and when it turns right or left it must continue flying forward?
Your spaceship must have component rigidbody (I think it does) and you get mode him using function GetComponent().AddForce. There you can choose the ForceMode. There are 4 kinds of force_mode:
Force - Add a continuous force to the rigidbody, using its mass.
Acceleration - Add a continuous acceleration to the rigidbody, ignoring its mass.
Impulse - Add an instant force impulse to the rigidbody, using its mass.
VelocityChange - Add an instant velocity change to the rigidbody, ignoring its mass.
So, choose the one you need and the spaceship must continue flying forward after turning
You've neglected your velocity variable. You're applying a scalar speed (momentum) in the direction of facing (transform.forward).
If you want to have a feel of momentum, you need to deal with Acceleration:
public CharacterController Ship;
public float AccelerationFactor = 1.0f;
public float BrakingFactor = 0.1f;
public float MaxSpeed = 20.0f;
private Vector3 Velocity;
void Update()
{
var totalBraking = Velocity.normalized * BrakingFactor;
var totalAcceleration = transform.forward * AccelerationFactor * Input.GetAxis("Vertical");
Velocity = Velocity + (totalAcceleration + totalBraking) * Time.deltaTime;
Velocity = Vector3.ClampMagnitude(Velocity, MaxSpeed);
Ship.Move(Velocity * Time.deltaTime);
}
I have a simple movement that relvolves around moving foward depending on where I look. The camera is made to follow the player. The problem I am havaing is that whenever I hit an object, my character(along with the camera) start spinning crazily all over the place. (I am new to coding)
Here is the code to the movement of where my character is facing :
public class Player : MonoBehaviour {
public float movementSpeed = 10;
public float turningSpeed = 60;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody> ();
}
void Update() {
float horizontal = Input.GetAxis("Mouse X") * turningSpeed *
Time.deltaTime;
transform.Rotate(0, horizontal,0);
float vertical = Input.GetAxis("Mouse Y")* turningSpeed * Time.deltaTime;
transform.Rotate(vertical, 0, 0);
float movement = Input.GetAxis("Foward") * movementSpeed *
Time.deltaTime;
transform.Translate(0, 0,movement);
}
}
(Sorry for bad format)
The Mouse X just makes it so that it rotates on the x axis of mouse(same with y axis). The Foward is just the vertical input preset in unity.
Here is the code to the lookAt player :
public class LookAtCamera : MonoBehaviour {
public GameObject target;
void LateUpdate() {
transform.LookAt(target.transform);
}
}
Answer
I believe your rigidbody is being more heavily affected than what you desire by the bounce force occuring as you hit the object.
Possible solutions
Depending on which collider type acts as your legs, the weight of the objects involved, what behaviour you intend and more the solution can vary.
Possible solution 1:
One option is to freeze the rotation of your object on it's Rigidbody component, you can decide which axes to freeze rotation on. If freezed they can't be pushed by outside forces.
Possible solution 2:
If you wish the player to only be affected by your script you can set the rigidbody kinematic, meaning that it only is affected by scripts and animation. This is a contrast to being set to dynamic where other objects can affect it.
Possible solution 3:
Play around with the angular drag and mass of the rigidbody to slow down rotation.