iTween.fadeTo() is not fading objects away - c#

I am trying to make an object slowly fade away and then get destroyed. I have been using iTween.fadeTo function to achieve the desired behavior. However, after the assigned time to finish the fadeTo() function, the object gets destroyed without fading away. I don't know what I need to set up to make the object fade away before get destroyed. (The code below is fixed to the desired behavior)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void horizontalMovement ()
{
mousePosition = Input.mousePosition;
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit)) {
if (hit.collider != null) {
GameObject[] tiles = GameObject.FindGameObjectsWithTag("Floor");
int interations = 0;
foreach (GameObject tile in tiles) {
interations = interations + 1;
float tilePosition = tile.transform.localPosition.x;
float hitPostion = hit.transform.gameObject.transform.localPosition.x;
float minimunValue = tilePosition - hitPostion;
if (minimunValue == 0) {
iTween.FadeTo(tile, iTween.Hash(
"alpha", 1f,
"amount", 0f,
"time", 1f,
"onCompleteTarget", gameObject,
"onComplete", "destroy",
"oncompleteparams", tile)
);
}
}
Debug.Log ("clean objects horizontally");
}
}
Debug.Log ("Horizontal Movement is working" + mousePosition);
}
public void destroy(GameObject anyObject){
Destroy (anyObject);
Debug.Log ("Item will be destroyed");
}

Instead of Destroy() method you could use nameYourObject.SetActive(false);
It will dissapear your object as well.

Related

Not understanding why raycast code isnt working

Here is the Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastControl : MonoBehaviour
{
LineRenderer line;
private Vector3 zeros;
public LayerMask EnemyLayer;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
zeros = new Vector3(0f, 0f, 0f);
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Debug.Log("Detected the click");
Vector3 mouse = mouseToWorld(Input.mousePosition);
Ray ray = new Ray(zeros, mouse);
RaycastHit hitData;
if (Physics.Raycast(ray, 10000, EnemyLayer))
{
Vector3[] linePos = new Vector3[] { transform.position, mouse };
line.SetPositions(linePos);
Debug.Log("You've hit a Zomboid!");
}
}
}
public Vector3 mouseToWorld(Vector3 mousePos)
{
mousePos = Input.mousePosition;
mousePos.z = Camera.main.nearClipPlane;
Vector3 mouse = Camera.main.ScreenToWorldPoint(mousePos);
mouse.z = 0f;
return mouse;
}
}
Note: I'm using Unity2d
I'm trying to use 0,0,0 and the location of my mouse to cast a ray starting from 0,0,0 and running through the mouse location on to the specified max distance in if(physics.Raycast(ray,maxDistance,EnemyLayer)). this, however, does not work. When I click on or behind the "Zombie" object I've created, I dont get a raycast hit detected.
I've been sure to make sure that the layer mask set in this script is the same one set in the Zombie object. My Debug.Log("You've made it this far!"); line activates so I know the Script is in the scene and is being read, but the Physics.Raycast(ray,10000,EnemyLayer)) NEVER returns true, and we know this because Debug.Log("You've hit a Zomboid!") never shows up in console.
Note: The object this script is attached to, Center, sits at 0,0,0. its transform.position = 0,0,0
Your help is greatly appreciated.
Physics and Physics2D are separate in Unity and don't interact with each other.
Physics2D.Raycast() belongs to Physics2D and only responds to Physics2D (BoxCollider2D, CircleCollider2D, PolygonCollider2D, etc.)
Physics.Raycast() belongs to Physics and only responds to Physics (BoxCollider, SphereCollider, MeshCollider, etc.)
You are using Physics.Raycast() when you should be using Physics2D.Raycast().
This is how you would do it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastControl : MonoBehaviour
{
LineRenderer line;
//private Vector3 zeros;
public LayerMask EnemyLayer;
// Start is called before the first frame update
void Start()
{
line = GetComponent<LineRenderer>();
//zeros = new Vector3(0f, 0f, 0f); not necessary this is the same as Vector3.zero
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Debug.Log("Detected the click");
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hit)
{
Vector3[] linePos = new Vector3[] { transform.position, hit.point};
line.SetPositions(linePos);
Debug.Log("You've hit a Zomboid!");
}
}
}
}```

Unity fix NavMeshAgent jerky movements?

Record of the problem
https://youtu.be/BpzHQkVQz5A
Explaining my problem
I'm programming a mobile game using Unity3D Engine. For my player movement, I'm using NavMeshAgent because it's for me the easiest and most efficient way to do it. But when I hit the play button and ask my player to move, the movements are jerky and it's not pleasant to see at all.
Do you have any idea to fix this problem ?!
Thank you in advance for your answers ! ^^
My code
This is my code :
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
NavMeshAgent agent;
Touch touch;
RaycastHit hit;
Ray ray;
// START FUNCTION
private void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// UPDATE FUNCTION
private void Update()
{
// TOUCH DETECTION
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
// A FINGER TOUCHED THE SCREEN
if (touch.phase == TouchPhase.Began)
{
// RETURN X, Y AND Z WORLD POS OF THE TOUCH SCREEN POS
ray = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
// MOVING PLAYER TO THE HIT POS
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
}
// SAME CODE USING MOUSE BUTTON
#if UNITY_EDITOR
if (Input.GetMouseButton(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if (hit.collider != null)
{
Vector3 hitVec = new Vector3(hit.point.x, hit.point.y + (GetComponent<Collider>().bounds.size.y / 2), hit.point.z);
agent.SetDestination(hitVec);
}
}
}
#endif
}
}
CameraFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// BRACKEYS CAMERA FOLLOW SCRIPT WITHOUT THE LOOKAT METHODE
public class CameraFollow : MonoBehaviour
{
public Transform target;
public float smoothSpeed = 0.2f;
public Vector3 offset;
void FixedUpdate()
{
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
}
}
The problem isn't the navmesh controller but the camera follow script.
One thing you could try is to move the camera position using only the desiredPosition or use Vector3.SmoothDamp:
private Vector3 velocity;
void LateUpdate(){
...
Vector3 desiredPosition = target.position + offset;
Vector3 smoothedPosition = Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothSpeed);
transform.position = smoothedPosition;
}
Also this is explained in a pinned comment on the Brackeys video

Android Drag Sprite code Unity 5

I'm new to Unity and have been following a tutorial on how to make a Captain Blaster 2D game, however I want to convert it to Android, I want to make the player controllable by dragging him across the screen with one finger and don't understand what's wrong with my code, anything helps, thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ShipControl : MonoBehaviour {
public float playerSpeed = 10f;
public GameControl gameController;
public GameObject bulletPrefab;
public float reloadTime = 1f;
private float elapsedTime = 0;
void Update()
{
elapsedTime += Time.deltaTime;
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay (touch.position);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100)) {
}
}
if (elapsedTime > reloadTime)
{
Vector3 spawnPos = transform.position;
spawnPos += new Vector3 (0, 1.2f, 0);
Instantiate (bulletPrefab, spawnPos, Quaternion.identity);
elapsedTime = 0f;
}
}
}
void OnTriggerEnter2D(Collider2D other)
{
gameController.PlayerDied ();
}
}
What I would do is add a bool called "dragging" and after you check if Raycast hit anything you also check if hit object is the player GameObject.
If it is then as long as user is not releasing the touch - make player's rigidbody move towards the touch position (so if there are any obstacles it simply doesn't move right through them).
Code would probably look like this (you should also add some timer to check if player released touch and set dragging bool to false):
public float playerSpeed = 10f;
public GameControl gameController;
public GameObject bulletPrefab;
public float reloadTime = 1f;
private float elapsedTime = 0;
private bool dragging = false;
void Update()
{
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay (touch.position);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, 100))
{
if(hit.collider.tag == "Player") // check if hit collider has Player tag
{
dragging = true;
}
}
if(dragging)
{
//First rotate the player towards the touch (should do some checks if it's not too close so it doesn't glitch out)
Vector3 _dir = Camera.main.ScreenToWorldPoint(touch.position) - transform.position;
_dir.Normalize();
float _rotZ = Mathf.Atan2(_dir.y, _dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, _rotZ - 90);
//Move towards the touch
transform.GetComponent<Rigidbody>().AddRelativeForce(direction.normalized * playerSpeed, ForceMode.Force);
}
}
}
}

Dragging and moving 2D gameObject

so as my previous threads show, I am creating a gameObject from sprites images at runtime using this code:
tex = Resources.Load<Texture2D>("pig") as Texture2D;
Sprite sprite = new Sprite();
sprite = Sprite.Create(tex, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f));
GameObject newSprite = new GameObject();
newSprite.AddComponent<Rigidbody2D>();
newSprite.GetComponent<Rigidbody2D>().gravityScale = 0f;
newSprite.AddComponent<ObjectMovement>();
newSprite.AddComponent<SpriteRenderer>();
SR = newSprite.GetComponent<SpriteRenderer>();
SR.sprite = sprite;
As you see I added a script "ObjectMovement", I want to check in this script if someone is dragging this particular gameObject and if so, make it follow the touch position, just to mention - this game is 2D. I never used RaysorRaycast so I am not sure where I gone wrong. Anyway here is my script code:
public SpriteRenderer selection=null;
void Update()
{
if (Input.touchCount >= 1)
{
foreach (Touch touch in Input.touches)
{
Ray ray = Camera.main.ScreenPointToRay(touch.position);
RaycastHit hit;
switch (touch.phase)
{
case TouchPhase.Began:
if (Physics.Raycast(ray, out hit, 100))
selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
break;
case TouchPhase.Moved:
selection.transform.position = new Vector2(selection.transform.position.x + touch.position.x / 10, selection.transform.position.y + touch.position.y / 10);
break;
case TouchPhase.Ended:
selection = null;
break;
}
}
}
}
So basically - when touching the screen, fire a ray and check which gameObject is in this position, when moving the finger make it follow it. Drag and drop. Thanks.
EDIT: I noticed the script is attached to every gameObject which is not effective, any ideas?
For 2D, you use RaycastHit2D and Physics2D.Raycast instead of RaycastHit and Physics.Raycast. Those are for 3D. Secondly, Make sure to attach a collider to the Sprite. Since this is a 2D game, the collider must have word "2D" in it. For example, Box Colider 2D from the Editor. You can also use Circle Collider 2D.
I noticed the script is attached to every gameObject which is not
effective, any ideas?
Just create an empty GameObject and attach that script to it. That's it.
Here is fixed version of your code:
float tempZAxis;
public SpriteRenderer selection;
void Update()
{
Touch[] touch = Input.touches;
for (int i = 0; i < touch.Length; i++)
{
Vector2 ray = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position);
RaycastHit2D hit = Physics2D.Raycast(ray, Vector2.zero);
switch (touch[i].phase)
{
case TouchPhase.Began:
if (hit)
{
selection = hit.transform.gameObject.GetComponent<SpriteRenderer>();
if (selection != null)
{
tempZAxis = selection.transform.position.z;
}
}
break;
case TouchPhase.Moved:
Vector3 tempVec = Camera.main.ScreenToWorldPoint(touch[i].position);
tempVec.z = tempZAxis; //Make sure that the z zxis never change
if (selection != null)
{
selection.transform.position = tempVec;
}
break;
case TouchPhase.Ended:
selection = null;
break;
}
}
}
That would only work on mobile but not on the Desktop Build. I suggest you implement IBeginDragHandler, IDragHandler, IEndDragHandler and override the functions that comes with them. Now, it will work with both mobile and desktop platforms.
Note: For the second solution you have to attach the script below to all Sprites you want to drag unlike the first script above.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Dragger : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Camera mainCamera;
float zAxis = 0;
Vector3 clickOffset = Vector3.zero;
// Use this for initialization
void Start()
{
//Comment this Section if EventSystem system is already in the Scene
addEventSystem();
mainCamera = Camera.main;
mainCamera.gameObject.AddComponent<Physics2DRaycaster>();
zAxis = transform.position.z;
}
public void OnBeginDrag(PointerEventData eventData)
{
clickOffset = transform.position - mainCamera.ScreenToWorldPoint(new Vector3(eventData.position.x, eventData.position.y, zAxis));
}
public void OnDrag(PointerEventData eventData)
{
//Use Offset To Prevent Sprite from Jumping to where the finger is
Vector3 tempVec = mainCamera.ScreenToWorldPoint(eventData.position) + clickOffset;
tempVec.z = zAxis; //Make sure that the z zxis never change
transform.position = tempVec;
}
public void OnEndDrag(PointerEventData eventData)
{
}
//Add Event Syste to the Camera
void addEventSystem()
{
GameObject eventSystem = new GameObject("EventSystem");
eventSystem.AddComponent<EventSystem>();
eventSystem.AddComponent<StandaloneInputModule>();
}
}

C# Parsing Error

I'm making a Game Called UnityCraft and I tried making a way to switch blocks!
Here is my Code:
using UnityEngine;
using System.Collections;
public class BuildScript : MonoBehaviour {
RaycastHit hit;
public int blockSelected = 1;
public Transform prefab;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Input.GetButtonDown(1)){
blockSelected = 1;
}
if(Input.GetButtonDown(2)){
blockSelected = 2;
}
if(blockSelected == 1){
prefab = dirt;
}
if(blockSelected == 2){
prefab = brick;
}
Ray ray = camera.ViewportPointToRay (new Vector3 (0.5f, 0.5f, 0));
Vector3 G = new Vector3 (Mathf.Round (hit.point.x), Mathf.Ceil (hit.point.y), Mathf.Round (hit.point.z));
if (Physics.Raycast (ray, out hit)) {
if (Input.GetMouseButtonDown (0)) {
Destroy (hit.collider.gameObject);
print ("Block Destroyed!");
}
if (Input.GetMouseButtonDown (1)) {
Instantiate (prefab, G, Quaternion.identity);
}
}
}
}
I have a prefab called brick and one called dirt, and they are linked to blocks.
I'm assuming that the problem you're referring to is in the line
if(Input.GetButtonDown(1)){
That won't work, because GetButtonDown does not have an integer argument. It takes a string, which you can find or define in the input manager.
From your code I do take it that you want to simply use number keys? In that case, don't use the GetButton calls, but use GetKey instead. So change your code to something like
if(Input.GetKeyDown(KeyCode.Keypad1)){
for the case where pressing 1 should trigger something.

Categories