I am new to A* Pathfinding i want to get the enemy ai to move only in x axis. How can i do that? this is what i got right now:
using UnityEngine;
using System.Collections;
using Pathfinding;
public class SimpleZombieAI : MonoBehaviour {
public Vector2 targetPosition;
public void Start (){
Seeker seeker = GetComponent<Seeker> ();
seeker.StartPath (transform.position, targetPosition, OnPathComplete);
}
public void OnPathComplete (Path p) {
Debug.Log ("Yay, we got a path back. Did it have an error? "+p.error);
}
}
but it goes in x and y and i want to make it go ONLY x. I hope someone can help me because i dont know where to post about this question.
I'm assuming your Seeker.StartPath function takes Vector parameters, so just passing the x values won't work. While I don't think you would really need to use pathfinding for a one-dimensional path, if that's what you want to use, here's a way that you might be able to achieve that.
public void Start (){
Seeker seeker = GetComponent<Seeker> ();
float myY = transform.position.y;
seeker.StartPath (transform.position, new Vector2(targetPosition.x,myY), OnPathComplete);
}
This will have your enemies move along their constant y-value line, while chasing from their own x-coordinate to the player's x-coordinate.
Related
I've been working on a game for the team seas game jam, and I'm trying to make a boat that will actually float, I've but ran into a issue, so to explain it the way the current script works is it checks for the position of some point on the boat and if the points are below the y level of the plane/water then it will add an upward force to that point. Here's that code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Floater : MonoBehaviour
{
public float depthBeforeSubmerged = 1f;
public float displacementAmount = 3f;
public Transform[] floatPoints;
public Transform Water;
private Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
foreach (Transform t in floatPoints)
{
if (t.position.y < Water.position.y) {
// if point is below water add force to said p
float displacementMultiplyer = Mathf.Clamp01(-t.position.y / depthBeforeSubmerged)
* displacementAmount;
rb.AddForceAtPosition(new Vector3(0f, Mathf.Abs(Physics.gravity.y) *
displacementMultiplyer, 0f), t.position,ForceMode.Acceleration);
}
}
}
}
This code works fine but the issue is that when I want to add waves to the plane/water the boat begins to float under the water, because shaders will edit the mesh plane but not the the y pose
of the plane/water it will not detect that and think the water is just sitting still with no elevation changes. So what I'm trying to do is get the vertices at the same x and z position as the points and get there y positions. Here's a diagram:
.
I'd do a racyast from the center of the cube straight up and add a force upward depending on the distance of that raycast, so as it gets lower underwater, it'll get forced up more. I dont know if there is any specific way to do it in the basic physics engine.
The cubes are in formation of a big square to create some kind of border so the player can't move further.
transform is the player the script is attached to the player.
When I move the player to one of the cubes close to it the distance is about 95 but it should 0.1f or 0.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;
public class DistanceCheck : MonoBehaviour
{
public Transform[] cubes;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < cubes.Length; i++)
{
var dist = Vector3.Distance(transform.position, cubes[i].transform.position);
if (dist <= 0.1f)
{
descriptionTextImage.SetActive(true);
text.text = "I can't move.";
}
else
{
text.text = "";
descriptionTextImage.SetActive(false);
}
}
}
}
When I'm using a break point on the line :
if (dist <= 0.1f)
dist is a bit more then 95. Maybe the distance is checked to another cube or in another point on the cube?
You are checking all cubes every time and using same "dist" variable every time.
So it detects deistance being less then 0.1f, but goes on and changes value of dist to test another cube.This is why you are getting higher values despite being right next to a cube.
You need 4 distance variables that are each measuring distances to its specific cube and do something if either of them gets too short.
Another flaw is that you are measuring distance to a point in a box, so depending which side of a box you are its going to be showing different values.
I would suggest instead of using cube Transforms, use their Colliders instead. And then I'd be looking for the closest point on the collider bounds. As it currently stands, you're checking for the distance of this object, to the origin of the cube, and it sounds to me like you simply want to find the distance to the cube/collider in general.
First, change the field type for your cubes:
public BoxCollider[] cubes;
Then find the distance like this:
var closestPoint = cubes[ i ].ClosestPointOnBounds ( transform.position );
var distance = Vector3.Distance( transform.position, closestPoint );
Now you should be getting a distance to the closest point to the cube/collider.
More information on ClosestPointOnBounds can be found here at the Unity docs.
screenshot hereI want to clamp Y-axis on a cube. I can do it in Unity camera. But, it does not react correctly when I am using it in Vuforia camera.
My problem was that the cube follows the camera. I would like the cube to stay in its position and ignore the AR camera position. I sense it has something to do with WorldtoViewpoint but I cannot figure it out. Can you teach me how to do this please? thankyou
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClampMovementController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 pos = transform.localPosition;
pos.y = Mathf.Clamp(transform.position.y, 0f, 0f);
transform.localPosition = pos;
}
}
This is my solution:
Actually its very simple. The INcorrect concept was my object attached to the AR camera, hence, object position is always moving related to camera position. Now. In order to make the object stays in its place. I need to get its localPosition. First. Store the localposition in Vector3 pos. And then do modification on Vector3 pos. At last, reassign the new value to the object localposition.
public class ClampMovementController : MonoBehaviour
{
public float currentPos;
public GameObject capsule;
void Update()
{
//store the value of object localPosition
Vector3 pos = capsule.transform.localPosition;
//modification on the value
pos.y = Mathf.Clamp(pos.y, currentPos, currentPos);
//rerassign the new value to the object localPosition
capsule.transform.localPosition = pos;
}
}
First of all your cube is moving with the camera because your image target is child of your ARCamera. Therefore, when you move the camera image target moves, then your cube moves as well. Make sure your ImageTarget has no parent.
I did not understand why you have to lock any movement in Y axis. I guess you are doing something wrong with lean touch when you move object. I have not used lean touch but i have achieved this with keyboard inputs. You can convert it to lean touch by modifying following script. Just add these line to your ImageTarget's DefaultTrackableEventHandler script:
//Variables for getting capsule and checking if ImageTarget is tracked
private bool isTracked = false;
private GameObject capsule;
Then create an Update method for getting input from user like this.
void Update()
{
if(isTracked)
{
if(Input.GetKey(KeyCode.W))
{
//using forward for moving object in z axis only.
//Also using local position since you need movement to be relative to image target
//Global forward can be very different depending on your World Center Mode
capsule.transform.localPosition += Vector3.forward * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.S))
{
capsule.transform.localPosition -= Vector3.forward * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A))
{
//Using Vector3.left and right to be make sure movement is in X axis.
capsule.transform.localPosition += Vector3.left * Time.deltaTime;
}
else if (Input.GetKey(KeyCode.D))
{
capsule.transform.localPosition += Vector3.right * Time.deltaTime;
}
}
}
As you can see there is no movement in Y axis because i used forward, left and right vectors to make sure movement in in only X and Y axis.
Last you have to make sure isTracked is updated. In order to do that you have to add isTracked = false; in OnTrackingLost method and isTracked = true; in OnTrackingFound method. Good luck!
I have tried both of these C#scripts to rotate my directional light:
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.rotation = Quaternion.Euler(transform.eulerAngles.x + 1.0f,
transform.eulerAngles.y,
transform.eulerAngles.z);
}
}
and
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.localEulerAngles = new Vector3(transform.localEulerAngles.x + 1.0f,
transform.localEulerAngles.y,
transform.localEulerAngles.z);
}
}
They both seem to function exactly the same: If I change transform.eulerAngles.y to transform.eulerAngles.y + 0.5f, the light will rotate along the y-axis, and the same works for the z-axis. However, when I try to do this with the x-axis, it will rotate until it hits 90º, at which point it will continue to attempt rotation but it immediately and continuously shoved back to 90º. If I reverse the direction, it does the same thing at -90º. For example, the rotation might be: 88.5,89.0,89.5,90.0, 90.5, 89.93, 90.24, 89.4, etc.
What is causing this clamping and how do I fix it?
I think this is what you are looking for: http://answers.unity3d.com/questions/187073/rotation-locks-at-90-or-270-degrees.html
In order to fix your problem, you need to use an additional vector, change it inside Update every frame, and then pass it to the eulerAngles propriety of the transform.
Vector3 vect = Vector3.zero;
float rotationSpeed = 10f;
void Start () {
vect = transform.eulerAngles; //Set the vect rotation equal to the game object's one
}
void Update ()
{
vect.x += rotationSpeed * Time.deltaTime;
//Pass unique eulerAngles representation to the object without letting Unity change it
transform.eulerAngles = vect;
}
This happens btw because there're multiple euler angles representation of a single physical rotation in the 3D space, and when you work directly on the eulerAngles propriety of the transform, Unity makes some work behind the scenes, which can lead to a gimbal lock.
Use Quaternions. It's what Unity3d uses internally and doesn't have any of the side effects of euler angles.
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
public Vector3 RotationAxis = Vector3.right;
Quaternion _startRotation;
float _rotationIncrement = 0;
void Start()
{
_startRotation = transform.rotation;
}
void Update ()
{
Quaternion rotationMod =
Quaternion.AngleAxis(_rotationIncrement, RotationAxis);
_rotationIncrement += 1;
transform.rotation = _startRotation * rotationMod;
}
}
However, you probably want to use something like Quaternion.RotateTowards or Quaternion.Lerp along with Time.time and a rate. You will get much smoother results that way.
if you only want to rotate along the X-axis then set the other axis as 0.
When reading this, keep in mind I'm new to both programming and Unity, so I might be missing some terms or tools Unity offer. Please elaborate your answers in an ELI5 manner. Thanks in advance!
I am currently working on some game-physics for a small personal project. Currently I've created a platform, a character and what should be, a following companion.
However, since I'm still not on a level, where I can create perfect code on own hand, I found an "enemy" script and tried to modify it a bit.
It Works to an extend, but it needs some tweaks which I hope I can help aquire with you guys.
This is how it looks now (the orange square is the companion)
It follows the player, and I can tweak the speed to fit as a companion, and not a player. However, as the Picture presents, the companion runs for the center of the player. What I want to create is a companion which follows the player, but still keeps a small gap from the player.
My first thoughts was to create some kind of permanent offset, but I fail to figure out how to do this without messing up the follow function.
I hope you can help me, it will be much appreciated!
Here's the code for reference.
Code attached to Player:
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
//In the editor, add your wayPoint gameobject to the script.
public GameObject wayPoint;
//This is how often your waypoint's position will update to the player's position
private float timer = 0.5f;
void Update ()
{
if (timer > 0) {
timer -= Time.deltaTime;
}
if (timer <= 0) {
//The position of the waypoint will update to the player's position
UpdatePosition ();
timer = 0.5f;
}
}
void UpdatePosition ()
{
//The wayPoint's position will now be the player's current position.
wayPoint.transform.position = transform.position;
}
}
Code attached to companion:
using UnityEngine;
using System.Collections;
public class FollowerOffset : MonoBehaviour {
//You may consider adding a rigid body to the zombie for accurate physics simulation
private GameObject wayPoint;
private Vector3 wayPointPos;
//This will be the zombie's speed. Adjust as necessary.
private float speed = 10.0f;
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
}
void Update ()
{
wayPointPos = new Vector3(wayPoint.transform.position.x, transform.position.y, wayPoint.transform.position.z);
//Here, the zombie's will follow the waypoint.
transform.position = Vector3.MoveTowards(transform.position, wayPointPos, speed * Time.deltaTime);
}
}
bump, I guess ? :)
You can use smooth follow script. I have created a sample class for you. This class has features to follow any given gameobject with some delay and offset. You will have to tweak some values according to your need.
using UnityEngine;
using System.Collections;
public class PlayerCompanion : MonoBehaviour
{
[SerializeField]
private GameObject wayPoint;
[SerializeField]
public Vector3 offset;
public Vector3 targetPos;//Edit: I forgot to declare this on firt time
public float interpVelocity;
public float cameraLerpTime = .1f;
public float followStrength = 15f;
// Use this for initialization
void Start ()
{
//At the start of the game, the zombies will find the gameobject called wayPoint.
wayPoint = GameObject.Find("wayPoint");
offset = new Vector3 (5,0,0);//input amount of offset you need
}
void FixedUpdate () {
if (wayPoint) {
Vector3 posNoZ = transform.position;
Vector3 targetDirection = (wayPoint.transform.position - posNoZ);
interpVelocity = targetDirection.magnitude * followStrength;
targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime);
transform.position = Vector3.Lerp (transform.position, targetPos + offset, cameraLerpTime);
}
}
}
Attach this class to your player companion, play with different values.
To preserve object orientation your companion schould not be anyways child of your main character.
Your wayPoint doesn't needs to be a GameObject but a Transform instead and your code will looks like better.
If your game is a 2D platform your and your companion needs to be backwards your player it probabli applys to just one axis (X?) so you can decrement your waiPoint in a more directly way by calculating it on your UpdatePosition function like this:
wayPoint.position = transform.position * (Vector3.left * distance);
where your "distance" could be a public float to easily setup.
so on your companion script Update just do:
transform.position = Vector3.MoveTowards(transform.position, wayPoint.position, speed * Time.deltaTime);
I can't test it right now so you could have problems with Vector3 multiply operations, just comment and I'll try to fix as possible ;)