Inside the script code I want add the possibility to change its sprite. So the player mouseover the sprite,it changes into the other sprite already added to the project. Can you provide me a sample code to do this?
var newSprite : Sprite;
function Start () {
print(gameObject.name);
}
void OnMouseEnter()
{
print("hii detected");
//targetGui.texture = hoverTex;
GetComponent(SpriteRenderer).sprite = newSprite;
}
void OnMouseExit()
{
}
You can make both of the sprite as gameObjects. Then disable the Sprite Renderer of the newSprite object and attach the script to the current Sprite (first sprite).
public GameObject newSprite;
private Vector3 currentSpritePosition;
void OnMouseEnter(){
//getting the current position of the current sprite if ever it can move;
currentSpritePosition = transform.position;
//then make it invisible
renderer.enabled = false;
//give the new sprite the position of the latter
newSprite.transform.position = currentSpritePosition;
//then make it visible
newSprite.renderer.enabled = true;
}
void OnMouseExit(){
//just the reverse process
renderer.enabled = true;
newSprite.renderer.enabled = false;
}
You can also diable at start as follows:
void Start(){
newSprite.renderer.enabled = false;
}
EDIT: You should add a collider to the current sprite for the OnMouseOver and OnMouseExit to work.
Related
The main goal of the script in this case is when the player is getting too close to the fire to slowly stop walking automatic wait some seconds then automatic rotate and start walking again and then stop again slowly.
The script is working when the player is entering the collider area this is the target variable position so the player is rotating back to where he was entered from.
The idea is to make something nice to prevent from the player to get into the fire. but i'm facing two problems.
The first problem is that in the script i'm using a box collider as the area to prevent from the player to get closer to the fire and it's hard to dynamic change the collider area shape to cover all sides.
This is a screenshot of the collider area :
I marked to possible places if the player is coming from closer to the fire when he enter/exit the collider area he is already inside the fire and it's hard to change the collider size and scale to cover this places too.
I wonder if using distance check instead of the box collider will be easier ? and if it is how to change the script to use distance check instead the box collider trigger enter and exit events ?
The second problem is that sometimes when the player got close to the fire and then rotating back outside the collider area when he exit at that point(position) the player is making a walking circle around the target position and then continue outside. not sure why the player is making sometimes a moving around the target point ?
The script is attached to the player :
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;
public class SpreadedFireDistanceCheck : MonoBehaviour
{
public Vector3 target;
public float rotationSpeed;
public GameObject descriptionTextImage;
public TextMeshProUGUI text;
public Transform player;
private Animator anim;
private ThirdPersonUserControl thirdPersonUserControl;
private bool startRotBack = false;
private bool rot = false;
private bool doOnce = true;
private bool getTargetPos = false;
float angle = 10;
// Start is called before the first frame update
void Start()
{
anim = player.GetComponent<Animator>();
thirdPersonUserControl = player.GetComponent<ThirdPersonUserControl>();
}
// Update is called once per frame
void Update()
{
if (startRotBack)
{
if (doOnce)
{
anim.SetTrigger("Idle Exit");
StartCoroutine(WaitTime());
doOnce = false;
}
if (rot)
{
anim.SetBool("Walk", true);
if (Vector3.Angle(player.transform.forward, target - player.transform.position) > angle)
{
Vector3 dir = target - player.transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Vector3 rotation = Quaternion.Lerp(player.transform.rotation, lookRotation, Time.deltaTime * rotationSpeed).eulerAngles;
player.transform.rotation = Quaternion.Euler(0f, rotation.y, 0f);
}
}
}
}
private void OnTriggerExit(Collider other)
{
if (other.name == "kid_from_space")
{
if (rot)
{
rot = false;
anim.SetBool("Walk", false);
anim.SetTrigger("Idle Enter");
thirdPersonUserControl.enabled = true;
getTargetPos = false;
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.name == "kid_from_space")
{
if (getTargetPos == false)
{
target = player.transform.position;
getTargetPos = true;
}
descriptionTextImage.SetActive(true);
text.text = "This flames are so hot, i better stay away.";
thirdPersonUserControl.enabled = false;
doOnce = true;
startRotBack = true;
}
}
private IEnumerator WaitTime()
{
yield return new WaitForSeconds(5f);
text.text = "";
descriptionTextImage.SetActive(false);
rot = true;
}
}
In general the script is working but this two problem i mentioned above is hard to solve.
The player have this components :
Animator , Rigidbody , Capsule Collider , Third Person User Control (Script) , Third Person Character (Script)
I'm making a 2D game and i have spawning potion items in a making potion scene first of all i want to make the item pop up after spown and go like in this video that i recorded from my game:
Spawned Item do not move like the original
what do i do to make the spawned (Cloned) Item move the same as the original potion item?
Secondly, i want to spawn random and more than one item (potion) each time the scene starts how do i do that knowing that i'm using this script that spawns only one object:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HerbSpawner : MonoBehaviour
{
//Here, we declare variables.
public GameObject objToSpawn;
public Transform groupTransform;
//public means the var is exposed in the inspector, which is super helpful.
// Start is called before the first frame update
Vector2 spawnPos;
void Start()
{
spawnPos = Camera.main.ViewportToWorldPoint(new Vector2(0.5f, 0.5f));
}
// Update is called once per frame
void Update()
{
//let's also spawn on button press:
if (Input.GetMouseButtonDown(0))
{
RaycastHit2D hit = Physics2D.GetRayIntersection(Camera.main.ScreenPointToRay(Input.mousePosition));
if (hit.collider && hit.collider.CompareTag("Bush"))
{
SpawnIt();
}
}
void SpawnIt()
{
Vector2 spawnPos = Camera.main.ViewportToWorldPoint(new Vector2(0.5f, 0.7f));
Instantiate(objToSpawn, spawnPos, Quaternion.identity, groupTransform);
}
}
}
please let me know if there is anyway to do it spawn multiple objects randomly and make the movement for the items to popup like in the video. This is teh script i used for that:
using System.Collections;
using UnityEngine;
using TMPro;
public class DragNDropItem : MonoBehaviour
{
public string itemName;
private bool dragging;
private Vector2 firstPos;
private Color spriteRenderer;
[SerializeField] private float speed = 3;
[SerializeField] private GameObject boiler;
public TMP_Text itemNameText;
private BoilerScript boilerScript;
public AudioSource drop;
void Awake()
{
// Initial position of the item
firstPos = transform.position;
boiler = GameObject.FindGameObjectWithTag("Boiler");
boilerScript = boiler.GetComponent<BoilerScript>();
spriteRenderer = gameObject.GetComponent<SpriteRenderer>().color;
}
void OnMouseDown()
{
dragging = true;
}
void OnMouseUp()
{
dragging = false;
if (Vector2.Distance(transform.position, boiler.transform.position) < 0.7f) // We control the distance between the item and the cauldron without using the collider.
{
itemNameText.text = itemName;
boilerScript.Potion(); // Checks the recipe's completion status each time an item is placed.
spriteRenderer.a = 0f;
gameObject.GetComponent<SpriteRenderer>().color = spriteRenderer;
StartCoroutine(Alpha());
}
else drop.Play(); // If the item is left
}
void Update()
{
if (dragging) // As soon as the item is clicked with the mouse, the item follows the mouse.
{
Vector2 mousePosition = MousePos();
transform.position = Vector2.Lerp(transform.position, mousePosition, speed * Time.deltaTime);
} else if (!dragging && (Vector2)transform.position != firstPos) // As soon as we stop clicking, it takes it back to its original place. While the item is in its original location, we are constantly preventing the code from running.
{
transform.position = Vector2.Lerp(transform.position, firstPos, speed * Time.deltaTime);
}
}
Vector2 MousePos() // position of mouse
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
private IEnumerator Alpha() // After a second the item becomes visible.
{
spriteRenderer.a = 1f;
yield return new WaitForSeconds(0.6f);
gameObject.GetComponent<SpriteRenderer>().color = spriteRenderer;
}
}
Your colliders aren't set to trigger. My guess is, when a clone is spawned, it collides with the existing potion object.
Im working on a first person shooter. I have an aim function, which puts the pistol right in front of the camera, to make it look like your holding it in front of you. Im trying to make it so the pistol will also rotate with the camera on the Z axis, so that way the pistol wont stay still, because that looks odd and gets in the way. To do this, I tried this:
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);, however this ends up rotating the gun very slightly around the z axis, and mainly rotating it around the y axis whenever I move my camera. I am a beginner programmer in Unity so please try to make answers more digestible to beginners so I can understand it. Here is my full script:
using System.Collections.Generic;
using UnityEngine;
public class PistolFire : MonoBehaviour
{
//Gun Properties
public float range = 50f;
public float damage = 10f;
//Sensitivity decrease for looking down the sights
public float downSights = 5f;
//Other vars
private playerGunControls playerGun;
private GameObject plrCam;
private Camera fpsCam;
private ParticleSystem muzzleFlash;
private GameObject impactEffect;
private bool aimed = false;
private GameObject aimPos;
private GunPickupRaycast GPR;
private GameObject handPos;
private GameObject Player;
// Start is called before the first frame update
void Start()
{
//Getting objects because gun is instantiated, so this is necessary
plrCam = GameObject.Find("Player Camera");
playerGun = plrCam.GetComponent<playerGunControls>();
fpsCam = plrCam.GetComponent<Camera>();
muzzleFlash = GetComponentInChildren<ParticleSystem>();
impactEffect = GameObject.Find("Impact Effect");
aimPos = GameObject.Find("aimPos");
GPR = plrCam.GetComponent<GunPickupRaycast>();
handPos = GameObject.Find("Hand Pos");
Player = GameObject.Find("Player");
}
// Update is called once per frame
void Update()
{
//Check for shoot button down
if (Input.GetButtonDown("Fire1"))
{
if (playerGun.holding == "Pistol")
{
Shoot();
}
}
//Check if aim button down
if (Input.GetButton("Fire2"))
{
if (playerGun.holding == "Pistol")
{
Aim();
}
}
//Check if no longer aiming to reset to normal
if (aimed == true && !(Input.GetButton("Fire2")))
{
Unaim();
}
}
void Shoot()
{
muzzleFlash.Play();
RaycastHit hit;
if(Physics.Raycast(plrCam.transform.position, plrCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Health health = hit.transform.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(damage);
}
//Instantiate the Impact Effect
GameObject IE = Instantiate(impactEffect, hit.point, Quaternion.identity);
Destroy(IE, 1.5f);
}
}
void Aim()
{
aimed = true;
Debug.Log("Aiming");
GPR.gun.transform.position = aimPos.transform.position;
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);
}
void Unaim()
{
GPR.gun.transform.position = handPos.transform.position;
Debug.Log("No longer aiming");
aimed = false;
}
}
I fixed my problem by making the gun a child of my camera instead of a child of my player.
I am making a small game that is based on the Roll-A-Ball tutorial from Unity, though I haven't used the actual tutorial. I incorporated a respawn mechanic, but if you are moving around when you die, then after you respawn, you still have that momentum after you land. I have tried to fix this, but I am not sure how since I am still pretty new at using Unity. I have a video that shows this: https://drive.google.com/open?id=1752bPBDVOe2emN_hmnlPaD4uaJQITpsP
Here is the C# script that handles respawn:
public class PlayerBehavior : MonoBehaviour
{
Rigidbody PlayerRB;
public bool Dead;
private int timer;
public GameObject Particles;
public bool InRespawn;
void Update()
{
PlayerRB = GetComponent<Rigidbody>();
if (Dead)
{
StartCoroutine("Respawn");
}
}
IEnumerator Respawn()
{
InRespawn = true; //Used to prevent movement during respawn.
PlayerRB.useGravity = false;
transform.position = new Vector3(0, 4, 0);
transform.rotation = new Quaternion(-80, 0, 0, 0); // Resets position.
Dead = false;
Instantiate(Particles, transform); // Adds respawn particle effect.
yield return new WaitForSeconds(2);
Destroy(this.gameObject.transform.GetChild(0).gameObject);
PlayerRB.useGravity = true;
PlayerRB.AddForce(0, 400, 0); // Does a little hop.
InRespawn = false; // Tells the game that respawn is finished.
}
}
Zero out the rigidbody's velocity when the respawn occurs:
IEnumerator Respawn()
{
PlayerRB.velocity = Vector3.zero;
// ... rest of method
}
As a sidenote, you probably don't need to run GetComponent on every frame. It's an expensive operation so it's best to do it as infrequently as you can get away with:
void Start()
{
PlayerRB = GetComponent<Rigidbody>();
}
void Update()
{
if (Dead)
{
StartCoroutine("Respawn");
}
}
If instead you would like to disable all physics interactions with the player while it is dead, you can set it to be kinematic during that time. Just be sure to unset isKinematic before adding force to it.
IEnumerator Respawn()
{
PlayerRB.isKinematic = true;
// ... rest of method
PlayerRB.isKinematic = false;
PlayerRB.useGravity = true;
PlayerRB.AddForce(0, 400, 0); // Does a little hop.
InRespawn = false; // Tells the game that respawn is finished.
}
make a bool in your code like this
bool isDead=false;
then make it true when you die
the add this into you update
if(isDead){
rb.velocity=vector3.zero;
}
this will stop you objects movements if it is dead
I am trying to create a Fruit Ninja style game on Unity 2D and I want to create a trail that follows where the player has "cut". I've tried to instantiate a "cut" object that contains the line renderer every time a user drags. However, the line renderer is not showing up. Can anyone correct any errors or suggest a new method?
public class CreateCuts : MonoBehaviour
{
public GameObject cut;
public float cutDestroyTime;
private bool dragging = false;
private Vector2 swipeStart;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dragging = true;
swipeStart = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
else if (Input.GetMouseButtonUp(0) && dragging)
{
createCut();
}
}
private void createCut()
{
this.dragging = false;
Vector2 swipeEnd = Camera.main.ScreenToWorldPoint(Input.mousePosition);
GameObject cut = Instantiate(this.cut, this.swipeStart, Quaternion.identity) as GameObject;
cut.GetComponent<LineRenderer>().positionCount = 1 ;
cut.GetComponent<LineRenderer>().enabled = true;
cut.GetComponent<LineRenderer>().SetPosition(0, this.swipeStart);
cut.GetComponent<LineRenderer>().SetPosition(1, swipeEnd);
Vector2[] colliderPoints = new Vector2[2];
colliderPoints[0] = new Vector2(0.0f, 0.0f);
colliderPoints[1] = swipeEnd - swipeStart;
cut.GetComponent<EdgeCollider2D>().points = colliderPoints;
Destroy(cut.gameObject, this.cutDestroyTime);
}
}
I expect there to be a line, but nothing shows up. There is also a warning stating that the SetPosition(1, swipeEnd) is out of bounds.
EDIT: Here are the settings of my cut object
1st part of cut object settings
2nd part of cut object settings
Positions tab of line renderer
I want to create a trail that follows where the player has "cut".
The word "trail" indicates that you should rather use a trail renderer!
Manual: https://docs.unity3d.com/Manual/class-TrailRenderer.html
API reference: https://docs.unity3d.com/ScriptReference/TrailRenderer.html
Back to your original question:
Your linerenderer probably is rendered but at a random position, because of Vector2 to Vector3 conversion, i dunno your project structure but this can be the case.
Please post a picture with one of your cut gameobject, that holds your linerenderer, and also extend the positions tab on the linerenderer so we can see your points xyz coordinates
Also apply the changes mentioned by commenters, because you really need 2 verticies for a line :P
Update:
public class CreateCuts : MonoBehaviour
{
public GameObject cut;
public float cutDestroyTime;
private bool dragging = false;
private Vector3 swipeStart;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dragging = true;
swipeStart = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Debug.Log("Swipe Start: " + swipeStart);
}
else if (Input.GetMouseButtonUp(0) && dragging)
{
createCut();
}
}
private void createCut()
{
this.dragging = false;
Vector3 swipeEnd = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Debug.Log("SwipeEnd: " + swipeEnd);
GameObject cut = Instantiate(this.cut, swipeStart, Quaternion.identity);
cut.GetComponent<LineRenderer>().positionCount = 2;
// why is it not enabled by default if you just instantiate the gameobject O.o?
cut.GetComponent<LineRenderer>().enabled = true;
cut.GetComponent<LineRenderer>().SetPositions(new Vector3[]{
new Vector3(swipeStart.x, swipeStart.y, 10),
new Vector3(swipeEnd.x, swipeEnd.y, 10)
// z is zero cos we are in 2d in unity up axis is Y we set it to 10 for visibility reasons tho}
});
// Commented out cos atm we are "debugging" your linerenderer
// Vector2[] colliderPoints = new Vector2[2];
// colliderPoints[0] = new Vector2(0.0f, 0.0f);
// colliderPoints[1] = swipeEnd - swipeStart;
// cut.GetComponent<EdgeCollider2D>().points = colliderPoints;
//Destroy(cut.gameObject, this.cutDestroyTime);
}
}