I am trying to create a maze game where the player can move only when it can see a sweet.
Currently the raycast is searching in every direction (360 degrees) But I only want the raycast to look directly Up,Left,Down,Right (instead of 360 degrees)... This way the player can only move when a sweet is placed in direct line of sight.
public function setTargetSweet(target:GameObject)
{
too = target.transform.position;
targetSweet = target;
var fwd = too - transform.position;
Debug.Log("Setting target sweet: " + target.name);
Debug.DrawRay(transform.position, fwd, Color.red, 5f);
Physics.Raycast (transform.position, fwd, hit);
if ( hit.collider.tag == "MoveToSweet") {
print ("Can See Sweet");
gotoSweet = true;
}
else
{
Debug.Log(hit.collider.name);
Debug.Log(hit.collider.tag);
gotoSweet = false;
}
}
You're doing ray casts in the direction of any sweet every time. You want four calls like Physics.Raycast(transform.position, Vector3.forward, hit) and check the hit between calls.
Related
I made a replica project to the game Knife Hit. And I'm having trouble with the following question, is my knife hitting the target before it hits it, or the target is detecting the hit before the knife even arrives. What causes the knife to fly around the target, where it should be stuck on the target. As shown in the image below. Consequently, the spawn of the knives that stay on the target, which is to hinder the gameplay, happen the same, are born and are flying around the target.
The code i use is this:
void Update()
{
if (shoot)
{
lastPosition = transform.position;
transform.position += Vector3.up * speed * Time.deltaTime;
RaycastHit2D hit = Physics2D.Linecast(lastPosition, transform.position);
if(hit.collider != null)
{
shoot = false;
if (hit.transform.tag == "Knife")
{
Level.Instance.HitWrong();
rigidbody.bodyType = RigidbodyType2D.Dynamic;
rigidbody.AddTorque(10, ForceMode2D.Impulse);
}
else
{
transform.position = new Vector3(transform.position.x, hit.point.y, transform.position.y);
transform.parent = hit.transform;
collider.enabled = true;
Level.Instance.HitSucced(rigidbody);
}
}
}
}
You need to make sure your 2D colliders are properly "cutout" outlined... My guess is that your 2D collider is really big around the knife or target
I create raycast2d script on my game for the HandGun and that works well when the near enemy on distance, taking damage to the enemy.
if (getShop.isPistol)
{
directionShoot = transform.up;
RaycastHit2D hit = Physics2D.Raycast(transform.position, directionShoot, shootDist, mask.value);
if (hit.collider != null)
{
Debug.DrawLine(transform.position, hit.point, Color.green);
hit.collider.gameObject.SendMessage("Damaged", damageTaken);
}
else
{
Debug.DrawLine(transform.position, directionShoot, Color.red);
}
GameObject bullet = Instantiate(bulletPrefab[0], firePoint[0].position, firePoint[0].rotation);
Bullet bulletScript = bullet.GetComponent<Bullet>();
bulletScript.velocity = firePoint[0].up * bulletForce * 10;
bulletScript.player = gameObject;
Destroy(bullet, 2f);
}
else if (getShop.isShotgun)
{
the shotgun
}
and for the shotgun, I recently use same as the Handgun instantiating one by one but I don't want to that so my question is can I use multiple raycast2d without raycastAll on the shotgun and how to add a spread bullet on it in topdown.
If your question is "can i make multiple raycasts per frame" the answer is yes, you can.
You would do something like
List<RaycastHit2D> hits = new List<RaycastHit2D>();
for(int i = 0; i < numberOfBulletsInShotgunShot; i++){
// modify your direction by some small amount here
RaycastHit2D hit = Physics2D.Raycast(transform.position, directionShoot, shootDist, mask.value);
if (hit.collider != null){
hits.Add(hit); // add hits to your list
}
}
// loop through deal with your hits here
Altering the direction slightly to spread your bullets out
hey guys i've something here to ask about how does really the velocity on unity works ??? i've been working on a project recently, i want to create the bouncing ball games, so whenever the ball hit the collider, it will be bounced depends on the position that have been hit.
i'm using the getComponent().velocity, but somehow the ball doesn't bounce really well, and whenever the ball hit the middle of collider, it should be bounced back without changing the direction .. please help !!! any help would be grateful ... here's my code :
float getBallPos(Vector2 ballPos, Vector2 boxPos, float boxWide ){
return (ballPos.x - boxPos.x)/boxWide ;
} ---> to get the bounce direction
void OnCollisionEnter2D (Collision2D other){
isHit = true;
if (other.gameObject.tag == "up") {
float x = getBallPos (transform.position, other.transform.position, other.collider.bounds.size.x);
Vector2 dir = new Vector2 (x, 1).normalized;
Debug.Log ("normalized : " + dir);
GetComponent<Rigidbody2D> ().velocity = dir * 5f;
}else if (other.gameObject.tag == "down") {
float x = getBallPos (transform.position, other.transform.position, other.collider.bounds.size.x);
Vector2 dir = new Vector2 (x, -1).normalized;
Debug.Log ("normalized : " + dir);
GetComponent<Rigidbody2D> ().velocity = dir * 5f;
}
}
You should create a Physics Material 2D with a high bounciness and low friction and apply it to your collider2D (you should see the values until you feel comfortable with it.
You create them in Assets->Create->Physics2D Material.
What you are trying yo do is simulate physics and it requires a somewhat complex mathematical model.
I have a issue with my 2D game in unity (pokemon style), I'm using transform.position to move the gameobjects.
I have a player and enemies that follow him, all is ok. But when the enemies make a collision, they begin to push each other
I need that nobody to be pushed when the enemies and player get a collision.
I tried to use kinematic in enemies, but the player can push them.
I tried to add a big amount of mass to the player, but he can push the enemies.
I tried to detect the collision in code with OnCollision, but when I cancel the enemy movement, they don't return to move.
----UPDATE----
I need the collision but without pushing between them, here is a video to illustrate the problem
https://www.youtube.com/watch?v=VkgnV1NOxlw
Just for the record, i'm using A* pathfinding script (http://arongranberg.com/astar/) here my enemies move script.
void FixedUpdate () {
if(path == null)
return;
if(currentWayPoint >= path.vectorPath.Count)
return;
Vector3 wayPoint = path.vectorPath [currentWayPoint];
wayPoint.z = transform.position.z;
transform.position = Vector3.MoveTowards (transform.position, wayPoint, Time.deltaTime * speed);
float distance = Vector3.Distance (transform.position, wayPoint);
if(distance == 0){
currentWayPoint++;
}
}
----UPDATE----
Finally I'll get the expected result,changing the rigidbody2D.isKinematic property to true when the target was close and stop it
Here is a video https://www.youtube.com/watch?v=0Zm0idUU75s
And the enemy movement code
void FixedUpdate () {
if(path == null)
return;
if(currentWayPoint >= path.vectorPath.Count)
return;
float distanceTarget = Vector3.Distance (transform.position, target.position);
if (distanceTarget <= 1.5f) {
rigidbody2D.isKinematic = true;
return;
}else{
rigidbody2D.isKinematic = false;
}
Vector3 wayPoint = path.vectorPath [currentWayPoint];
wayPoint.z = transform.position.z;
transform.position = Vector3.MoveTowards (transform.position, wayPoint, Time.deltaTime * speed);
float distance = Vector3.Distance (transform.position, wayPoint);
if(distance == 0){
currentWayPoint++;
}
}
You can do this in several ways,
You can use Physics2D.IgnoreCollision
Physics2D.IgnoreCollision(someGameObject.collider2D, collider2D);
Make sure that you do the IgnoreCollision call before the collision occurs, maybe when objects instantiate.
or alternatively you can use, Layer Collision Matrix
Unity Manual provides information on using this. This simply does the collision avoidance by assigning different GameObjects to different layers. Try:
Edit->Project Settings->Physics
Or if you want it to just stop moving, You can easily do it like,
bool isCollided = false;
// when when OnCollisionEnter() is called stop moving.
//maybe write your move script like
void Move() {
if(!isCollided) {
// move logic
}
}
I have an object called 'Player' in my scene.
I also have multiple objects called 'Trees'.
Now I'd like whenever the user clicks on a 'Tree', the 'Player' to move slowly to that position (using Lerp or moveTowards) is both O.K for me.
Now I have 2 issues with this code:
I'd like this code to be generic
Whenever I click a tree object I'd like this to move the player towards that tree. I don't want to write up this script and attach it to each tree object.
Where should I put the script?
Currently I attach this code to every tree object.
How should I write it down so that it applies to every tree object
in the scene?
If another click is made while moving, cancel previous movement and start moving to new position
How should I write it so that if I click on another object while the
player is moving towards another object that was clicked, the players stops moving towards it's previous position, and starts
moving towards the new point.
I'm having some trouble adjusting to the new UnityScript thingy. I come strictly from a Javascript background and it really seems like the 2 of them are languages with very different semantics. So if someone answers this with code(which is what I would want:) ), I'd appreciate some verbose comments as well.
I currently do this:
var playerIsMoving = false;
Public playerObject: Gameobject; //I drag in the editor the player in this public var
function update(){
var thisTreePosition = transform.point; //this store the X pos of the tree
var playerPosition = player.transform.point;
if(playerIsMoving){
player.transform.position = Vector2.MoveTowards(playerPosition, thisTreePosition, step);
}
}
function OnMouseDown(){
playerIsMoving = true;
}
I'm writing this from home where I don't have Unity and I forgot the code syntax therefore expect the above code to have typos or issues, at work it works just fine, apart from being very crude and unsophisticated.
I would recommend you to put the movement Script on the player. And how abour using Raycast to the test whether you hit a tree?
http://docs.unity3d.com/ScriptReference/Physics.Raycast.html
Vector3 positionToWalkTo = new Vector3();
void Update() {
if (Input.GetMouseButtonDown(0)) {
RaycastHit hit;
Ray ray = new Ray(transform.position, direction);
if (Physics.Raycast(ray, out hit))
if (hit.gameObject.tag.Equals("tree")){
positionToWalkTo = hit.gameObject.transform.position;
}
}
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, positionToWalkTo, step);
}
To get something like this running, you should tag all the trees.
'JavaScript'
var target: Transform;
// Speed in units per sec.
var speed: float;
function Update () {
if (Input.GetMouseButtonDown(0)) {
var hit: RaycastHit;
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
// Raycasting is like shooting something into the given direction (ray) and hit is the object which got hit
if (Physics.Raycast(ray, hit)) {
if (hit.gameObject.tag = "tree")
target = hit.gameObject.transform.position; // Sets the new target position
}
}
// The step size is equal to speed times frame time.
var step = speed * Time.deltaTime;
// Move our position a step closer to the target.
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
Okay, so I've done it myself (with some help from Freshchris's answer).
Here it is:
var target:Vector2;
var targetObject:GameObject;
var initialY:float;
var tolerance = 1;
var speed = 3;
var isMoving = false;
function Start(){
target = transform.position;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var hit: RaycastHit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); //raycast the scene
// if we hit something
if (hit.collider != null) {
isMoving=true; //it should start moving
targetObject = hit.collider.gameObject; //the target object
target = hit.collider.gameObject.transform.position;
}
}
// The step size is equal to speed times frame time.
var step = speed * Time.deltaTime;
// if it should be moving - move it - and face the player to the correct direction
if (isMoving){
if(transform.position.x>target.x){
gameObject.transform.localScale.x = -0.7;
}else {
gameObject.transform.localScale.x = 0.7;
}
transform.position = Vector2.MoveTowards(transform.position, target, step);
}
// if it reached the target object by a specified tolerance, tell it to stop moving
if(isMoving){
if((transform.position.x < target.x+tolerance)&&(transform.position.x > target.x-tolerance)){
print("position reached"); //this is fired just once since isMoving is switched to false just one line below
print(targetObject);
isMoving=false;
}
}
}