For my car war game, I have generated skid marks as the car takes a turn.
It's working properly, now after a few seconds passed, I want to reduce its alpha and remove it from the game. I have used trail renderer to generate skid marks.
what shader do I require to assign to the material?
which way I can reduce its alpha?
At present, I have used this kind of trail renderer material:
Now for reducing alpha gradually, I have this kind of code:
private IEnumerator Start()
{
Material myMaterial = GetComponent<Renderer>().material;
while (true)
{
yield return new WaitForSeconds(1f);
// check whether this skid trail has finished
// (the Wheel script sets the parent to null when the skid finishes)
if (transform.parent.name == "SkidTrailsDetachedParent")
{
// set the start colour
//Color startCol = GetComponent<Renderer>().material.color;
//Color startCol = myMaterial.GetColor("_EmisColor");
Color startCol = myMaterial.GetColor("_TintColor");
// wait for the persist time
yield return new WaitForSeconds(persistTime);
float t = Time.time;
// fade out the skid mark
while (Time.time < t + fadeDuration)
{
float i = Mathf.InverseLerp(t, t + fadeDuration, Time.time);
//myMaterial.color = startCol * new Color(1, 1, 1, 1 - i);
//myMaterial.SetColor("_EmisColor", startCol * new Color(1f, 1f, 1f, 1f - i));
myMaterial.SetColor("_TintColor", startCol * new Color(1f, 1f, 1f, 1f - i));
yield return null;
}
// the object has faded and is now done so destroy it
Destroy(gameObject);
}
}
}
Still, it's not working for me.
TrailRenderer has a property named endColor that you could set the alpha of the Color so that the line fades to the end.
void Start()
{
Color noAlphaEndColor = line.endColor;
line.endColor = new Color(noAlphaEndColor.r, noAlphaEndColor.g, noAlphaEndColor.b, 0.0f);
}
void Update()
{
if (line.endColor.a < 0.001)
{
Destroy(gameObject);
}
}
Related
this code does so when I press the A key or the B key, the elevator stops upwards on the first or second floor.
The question is
How do I modify the code that when the elevator is on the second floor, for example, and I press the A key again to make the elevator go down to the first floor?
Question two
If I replace
if (Input.GetKey (KeyCode.A)) {}
with this
if (Input.GetKeyUp (KeyCode.Keypad1)) {}
so the code does not work. Why?
Thank you for advice
Sorry for the bad English. Here is the code
public GameObject lift;
private bool keyHHit=false;
private bool keyHHitB=false;
void Update ()
{
if (Input.GetKey(KeyCode.B))
{
keyHHit=true;
}
if( keyHHit==true)
{
if(transform.localPosition.y >= 14.52)
{
transform.Translate(new Vector3(0, 0, 0) * 2 * Time.deltaTime, Space.Self);
}
else
{
transform.Translate(new Vector3(0, 2, 0) * 2 * Time.deltaTime, Space.Self);
}
}
if (Input.GetKey(KeyCode.A))
{
keyHHitB=true;
}
if( keyHHitB==true)
{
if(transform.localPosition.y >= 8.52)
{
transform.Translate(new Vector3(0, 0, 0) * 2 * Time.deltaTime, Space.Self);
}
else
{
transform.Translate(new Vector3(0, 2, 0) * 2 * Time.deltaTime, Space.Self);
//transform.Translate(Vector3.up * 0.05f);
}
}
}
So if I understand you correctly
you have two or 3 floors (doesn't matter, could be more later).
Once you press a button you want to move towards the target floor until you reach there. "Lock" input meanwhile
Once you reached a floor "unlock" Input again and allow to also go down if the current floor is above the target floor
I would use a Coroutine and Vector3.Lerp for this.
First lets have a class for floors so it is easier to add additional floors later
[Serializable]
public class FloorSetting
{
public KeyCode Key;
public Vector3 Position;
}
Then simply have an array of all floors target positions and according keys
// Configure these floors in the Inspector
// simply add the entries you need and adjust buttons and target positions
[SerializeField] private FloorSetting[] floors;
[SerializeField] private float moveUnitsPerSecond = 1f;
// This flag is for blocking any Input while moving
// thus preventing concurrent routines
private bool isMoving;
private void Update()
{
// if already moving do nothing
if(isMoving) return;
// check if any of the configured keys was pressed and start moving
// towards the according position
foreach(var floor in floors)
{
// You want to use GetKeyDown to only get the first press event
// you don't care about continues press since you will keep moving automatically until reaching the floor
if(Input.GetKeyDown(floor.Key))
{
StartCoroutine(MoveRoutine(floor.Position));
}
}
}
private IEnumerator MoveRoutine(Vector3 targetPosition)
{
// block concurrent routine
if(isMoving) yield break;
isMoving = true;
// Get the duration of movement
var startPosition = transform.position;
var duration = Vector3.Distance(startPosition, targetPosition) / moveUnitsPerSecond;
// Move smoothly towards the target position and add some easing
var timePassed = 0f;
while(timePassed <= duration)
{
// A interpolation factor between 0 and 1
var factor = timePassed / duration;
// optionally add ease-in and out
factor = Mathf.SmoothStep(0, 1, factor);
// Set the position to an interpolated position between start and target depending on the factor
transform.position = Vector3.Lerp(startPosition, targetPosition, factor);
// increase by the time passed since last frame
timePassed += Time.deltaTime;
// Tells Unity to "pause" the routine here, render this frame
// and continue from here in the next frame
yield return null;
}
// Just to be sure in he end set it to hard position
transform.position = targetPosition;
// optionally add some cooldown in seconds
yield return new WaitForSeconds(1f);
// Release the lock so next move can start now
isMoving = false;
}
If you don't need the easing you could as well also implement it lot easier using Vector3.MoveTowards like e.g.
while(!Mathf.Approximately(Vector3.Distance(transform.position, targetPosition), 0)
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveUnitsPerSecond);
yield return null;
}
transform.position = targetPosition;
Note: Typed on smartphone but I hope the idea gets clear
I'm fairly new to coding, I'm still trying to develop that logic of thinking to help me create the solutions I'm wanting for games. Currently, I'm in Unity trying to create a 2D GameObject that's a wall hiding a secret door. I want that GameObject to fade out (about 90%) when the player GameObject triggers it, revealing the space behind and the hidden door.
So far, I've managed to figure out how to render the "secret wall" GO inactive on the trigger, so it disappears, but this doesn't produce the visual that I'm going for. As I said, I'm still working on developing that coder's way of thinking, so while I've done a lot of research to solve this problem, many of the results I don't readily understand.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SecretDoor1 : MonoBehaviour {
void OnTriggerEnter2D (Collider2D SecretDoorTrig) {
if (SecretDoorTrig.gameObject.tag == "Player") {
GetComponent<SpriteRenderer> ().enabled = false;
}
else {
GetComponent<SpriteRenderer> ().enabled = true;
}
}
void OnTriggerExit2D (Collider2D SecretDoorTrig) {
if (SecretDoorTrig.gameObject.tag == "Player") {
GetComponent<SpriteRenderer> ().enabled = true;
}
else {
GetComponent<SpriteRenderer> ().enabled = false;
}
}
}
Fading a Sprite is almost the-same as moving GameObject over time except that you modify its alpha instead of it's position.
The three most important stuff about fading an Object are Time.deltaTime, Mathf.Lerp/Color.Lerp and coroutine. You need to understand how these work together.
Start coroutine, use Time.deltaTime to increment a variable. That variable is used to use to determine how much that function has ran. In a for/while loop, use that variable that is incremented every-frame and the duration you want the fade to happen to generate the alpha with the help of the Mathf.Lerp function. Create new color with that alpha and and assign it to the Sprite.
This is done every frame until that variable that is incremented with Time.deltaTime reaches the duration you want to the fade to happen within.
Here is a simple SpriteRenderer fade function:
public SpriteRenderer spriteToFade;
IEnumerator fadeOut(SpriteRenderer MyRenderer, float duration)
{
float counter = 0;
//Get current color
Color spriteColor = MyRenderer.material.color;
while (counter < duration)
{
counter += Time.deltaTime;
//Fade from 1 to 0
float alpha = Mathf.Lerp(1, 0, counter / duration);
Debug.Log(alpha);
//Change alpha only
MyRenderer.color = new Color(spriteColor.r, spriteColor.g, spriteColor.b, alpha);
//Wait for a frame
yield return null;
}
}
If you want it to fade in, change Mathf.Lerp(1, 0, counter / duration); to Mathf.Lerp(0, 1, counter / duration); which will make the alpha go from 0 to 1 over-time instead of 1 to 0.
From the example above, writing a fade-out and fade-in functions only requires a way to tell the function to change the alpha from 1 to 0 or from 0 to 1. You can make the function use a boolean or enum variable to determine which type of fade to perform. Of-course, you can separate the fade-in/fade-out functions but it's good to have it in one function.
Here is the extended version of that function that supports fade-in and fade-out. It also supports almost all GameObjects like MeshRenderer(3D), SpriteRenderer(2D), Image, RawImage....You can extend it to support more components that's missing.
IEnumerator fadeInAndOut(GameObject objectToFade, bool fadeIn, float duration)
{
float counter = 0f;
//Set Values depending on if fadeIn or fadeOut
float a, b;
if (fadeIn)
{
a = 0;
b = 1;
}
else
{
a = 1;
b = 0;
}
int mode = 0;
Color currentColor = Color.clear;
SpriteRenderer tempSPRenderer = objectToFade.GetComponent<SpriteRenderer>();
Image tempImage = objectToFade.GetComponent<Image>();
RawImage tempRawImage = objectToFade.GetComponent<RawImage>();
MeshRenderer tempRenderer = objectToFade.GetComponent<MeshRenderer>();
Text tempText = objectToFade.GetComponent<Text>();
//Check if this is a Sprite
if (tempSPRenderer != null)
{
currentColor = tempSPRenderer.color;
mode = 0;
}
//Check if Image
else if (tempImage != null)
{
currentColor = tempImage.color;
mode = 1;
}
//Check if RawImage
else if (tempRawImage != null)
{
currentColor = tempRawImage.color;
mode = 2;
}
//Check if Text
else if (tempText != null)
{
currentColor = tempText.color;
mode = 3;
}
//Check if 3D Object
else if (tempRenderer != null)
{
currentColor = tempRenderer.material.color;
mode = 4;
//ENABLE FADE Mode on the material if not done already
tempRenderer.material.SetFloat("_Mode", 2);
tempRenderer.material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
tempRenderer.material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
tempRenderer.material.SetInt("_ZWrite", 0);
tempRenderer.material.DisableKeyword("_ALPHATEST_ON");
tempRenderer.material.EnableKeyword("_ALPHABLEND_ON");
tempRenderer.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
tempRenderer.material.renderQueue = 3000;
}
else
{
yield break;
}
while (counter < duration)
{
counter += Time.deltaTime;
float alpha = Mathf.Lerp(a, b, counter / duration);
switch (mode)
{
case 0:
tempSPRenderer.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 1:
tempImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 2:
tempRawImage.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 3:
tempText.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
case 4:
tempRenderer.material.color = new Color(currentColor.r, currentColor.g, currentColor.b, alpha);
break;
}
yield return null;
}
}
Usage:
GameObject to fade:
public GameObject SpriteRend;
Fade-out in 3 seconds
StartCoroutine(fadeInAndOut(SpriteRend, false, 3f));
Fade-in in 3 seconds
StartCoroutine(fadeInAndOut(SpriteRend, true, 3f));
The way I have accomplished this has been change the alpha on the sprite color.
Color(R,G,B,A). A is the alpha.
SpriteRenderer.color = new Color(1f,1f,1f,1f) is opaque.
SpriteRenderer.color = new Color(1f,1f,1f,.5f) is about 50%
transparent.
SpriteRenderer.color = new Color(1f,1f,1f,0f) is about
100% transparent, sprite cannot be seen.
I want to animate my score text into a wavy animation each time the player picks up a coin as well as make another wavy text animation but going the opposite way each time the player loses some coins. I already have a code (shown below) to make a certain text do a wavy animation, however to do this I assigned each character of the text to either go up or down to initially make a wavy animation, as shown here:
.
My problem is: If I were to do this method for the score text, there is no telling how much coins the player will get and so it will make it difficult for me to estimate how much characters I would need for the score text as the possibility of the player adding a new digit to the score is kind of random.
So is there a way for me to create a wavy text animation to my score text? Thank you!
public GameObject WaveTextObj, text1, text2, text3, text4;
// Use this for initialization
void Start () {
text1.SetActive (false);
text2.SetActive (false);
text3.SetActive (false);
text4.SetActive (false);
StartCoroutine (WaveEffect ());
}
IEnumerator WaveEffect() {
while (true) {
WaveTextObj.SetActive (true);
yield return new WaitForSeconds (0.3f);
text1.SetActive (true);
yield return new WaitForSeconds (0.08f);
text2.SetActive (true);
yield return new WaitForSeconds (0.17f);
text3.SetActive (true);
yield return new WaitForSeconds (0.19f);
text4.SetActive (true);
yield return new WaitForSeconds(0.4f);
WaveTextObj.SetActive (false);
}
}
NEW UPDATE
text = "Testing";
string[] characters = new string[text.Length];
for (int i = 0; i < text.Length; i++)
{
characters[i] = text[i].ToString();
}
Use Mathf.Sin(Time.time)
public GameObject WaveTextObj;
public GameObject textPrefab;
IEnumerator WaveEffect(string text) {
//clear out the existing text
while(WaveTextObj.transform.childCount > 0) {
Destroy(WaveTextObj.transform.GetChild(0));
}
//create new text
float scalar = 0.1f;
float timeScalar = 3;
for (int i = 0; i < text.Length; i++)
{
GameObject o = Instantiate(textPrefab, new Vector3(i * scalar,0,0), Quaternion.Identity, WaveTextObj.transform)
o.GetComponent<Text>().text = text[i].ToString();
}
//animate text
while (true) {
int i = 0;
foreach (Transform child in transform) {
Vector3 p = child.localPosition;
// By setting each text object's y position to a value controlled by a sine wave,
// they will jiggle up and down. Their index in the string handles each letter being
// at a different point on the wave.
p.y = Mathf.Sin((Time.time + i * scalar) * timeScalar) * scalar;
child.localPosition = p;
i++;
}
yield return new WaitForEndOfFrame();
}
}
Up to you to figure out how you want exit the loop. Several values are arbitrary.
Problem :
I want to make prototype for cleaning windows (I mean cleaning dirty windows) in unity.
I was searching about this subject and finding that I can change pixel by Texture2D.SetPixel().
I try to do it by this method, First I enabled read/write of texture and try this method but nothing happened on my sprite.
So I want to ask it if it's possible to change alpha of the sprite that is clicked by mouse or touched to show the below sprite of original one !?
My Code :
private RaycastHit2D hitInfo;
private SpriteRenderer spriteRendererComponent;
private Color zeroAlpha;
// Use this for initialization
void Start ()
{
spriteRendererComponent = transform.GetComponent<SpriteRenderer>();
zeroAlpha = Color.blue;
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButton(0))
{
MouseClick();
}
}
public void MouseClick()
{
Vector2 mousePosition = Vector2.zero;
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
hitInfo = Physics2D.Raycast(mousePosition, Vector2.zero);
if (hitInfo)
{
spriteRendererComponent.sprite.texture.SetPixel((int)hitInfo.point.x, (int)hitInfo.point.y, zeroAlpha);
spriteRendererComponent.sprite.texture.Apply();
}
}
Answer :
You can use this thread for Optimizing of changing pixels of sprite
I've found answer about changing pixels of sprite (Painting)
public float radius;
public Color InitialColor;
private RaycastHit2D hitInfo;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (CustomInput.ControlStay())
{
hitInfo = CustomInput.ClickednTouched().hitInfo;
if (hitInfo)
{
UpdateTexture();
}
}
}
public Texture2D CopyTexture2D(Texture2D copiedTexture2D)
{
float differenceX;
float differenceY;
//Create a new Texture2D, which will be the copy
Texture2D texture = new Texture2D(copiedTexture2D.width, copiedTexture2D.height);
//Choose your filtermode and wrapmode
texture.filterMode = FilterMode.Bilinear;
texture.wrapMode = TextureWrapMode.Clamp;
//Center of hit point circle
int m1 = (int)((hitInfo.point.x + 2.5f) / 5 * copiedTexture2D.width);
int m2 = (int)((hitInfo.point.y + 2.5f) / 5 * copiedTexture2D.height);
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
differenceX = x - m1;
differenceY = y - m2;
//INSERT YOUR LOGIC HERE
if (differenceX * differenceX + differenceY * differenceY <= radius * radius)
{
//This line of code and if statement, turn all texture pixels within radius to zero alpha
texture.SetPixel(x, y, InitialColor);
}
else
{
//This line of code is REQUIRED. Do NOT delete it. This is what copies the image as it was, without any change
texture.SetPixel(x, y, copiedTexture2D.GetPixel(x, y));
}
}
}
//This finalizes it. If you want to edit it still, do it before you finish with Apply(). Do NOT expect to edit the image after you have applied.
texture.Apply();
return texture;
}
public void UpdateTexture()
{
SpriteRenderer mySpriteRenderer = gameObject.GetComponent<SpriteRenderer>();
Texture2D newTexture2D = CopyTexture2D(mySpriteRenderer.sprite.texture);
//Get the name of the old sprite
string tempName = mySpriteRenderer.sprite.name;
//Create a new sprite
mySpriteRenderer.sprite = Sprite.Create(newTexture2D, mySpriteRenderer.sprite.rect, new Vector2(0.5f, 0.5f));
//Name the sprite, the old name
mySpriteRenderer.sprite.name = tempName;
//Update the material
//If you have multiple sprites, you will want to do this in a loop
//mySpriteRenderer.material.mainTexture = newTexture2D;
//mySpriteRenderer.material.shader = Shader.Find("Unlit/Transparent");
}
Another problem :
Finding pixel on sprite :
In Unity3d we have RaycastHit.textureCoord but it doesn't exist anymore in 2D. I was searching about this problem, a lot but I didn't find anything useful.
So I want to know the solution for this problem and I'm wondering why method like textureCoord in 3D doesn't exist in 2D.
Answer :
I've found answer again as you see in the previous code for finding pixel on sprite.
Thread : Finding pixel on sprite in Unity
Check this out!
I have fixed your script. Works on different texture sizes. Different texture places and camera size. Require box collider 2d.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
public float radius;
public Color InitialColor;
private RaycastHit2D hitInfo;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
hitInfo = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
if (hitInfo)
{
UpdateTexture();
}
}
if (Input.GetMouseButtonUp(0))
{
Resources.UnloadUnusedAssets();
}
}
public Texture2D CopyTexture2D(Texture2D copiedTexture2D)
{
float differenceX;
float differenceY;
//Create a new Texture2D, which will be the copy
Texture2D texture = new Texture2D(copiedTexture2D.width, copiedTexture2D.height);
//Choose your filtermode and wrapmode
texture.filterMode = FilterMode.Bilinear;
texture.wrapMode = TextureWrapMode.Clamp;
//Center of hit point circle
int m1 = (int)((hitInfo.point.x - hitInfo.collider.bounds.min.x) * (copiedTexture2D.width / hitInfo.collider.bounds.size.x));
int m2 = (int)((hitInfo.point.y - hitInfo.collider.bounds.min.y) * (copiedTexture2D.height / hitInfo.collider.bounds.size.y));
//Vector2 extremeScreenPoint = Camera.main.ScreenToWorldPoint(new Vector2(0, 0));
//Debug.Log("extremeScreenPoint= " + extremeScreenPoint.x
// + " hitInfo.point.x =" + hitInfo.point.x
// //+ " mousePosition =" + Camera.main.ScreenToWorldPoint(Input.mousePosition).x
// + " bounds.min =" + hitInfo.collider.bounds.min .x
// + " bounds.max =" + hitInfo.collider.bounds.max .x
// + " size =" + hitInfo.collider.bounds.size.x
// + " hit =" + (hitInfo.point.x - hitInfo.collider.bounds.min.x)
// + " pixels =" + (hitInfo.point.x - hitInfo.collider.bounds.min.x) * (copiedTexture2D.width / hitInfo.collider.bounds.size.x)
// );
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
differenceX = x - m1;
differenceY = y - m2;
//INSERT YOUR LOGIC HERE
if (differenceX * differenceX + differenceY * differenceY <= radius * radius)
{
//This line of code and if statement, turn all texture pixels within radius to zero alpha
texture.SetPixel(x, y, InitialColor);
}
else
{
//This line of code is REQUIRED. Do NOT delete it. This is what copies the image as it was, without any change
texture.SetPixel(x, y, copiedTexture2D.GetPixel(x, y));
}
}
}
//This finalizes it. If you want to edit it still, do it before you finish with Apply(). Do NOT expect to edit the image after you have applied.
texture.Apply();
//DestroyImmediate(copiedTexture2D, true);
return texture;
}
public void UpdateTexture()
{
SpriteRenderer mySpriteRenderer = gameObject.GetComponent<SpriteRenderer>();
Texture2D newTexture2D = CopyTexture2D(mySpriteRenderer.sprite.texture);
//Get the name of the old sprite
string tempName = mySpriteRenderer.sprite.name;
//Create a new sprite
mySpriteRenderer.sprite = Sprite.Create(newTexture2D, mySpriteRenderer.sprite.rect, new Vector2(0.5f, 0.5f));
//Name the sprite, the old name
mySpriteRenderer.sprite.name = tempName;
//Update the material
//If you have multiple sprites, you will want to do this in a loop
//mySpriteRenderer.material.mainTexture = newTexture2D;
//mySpriteRenderer.material.shader = Shader.Find("Unlit/Transparent");
}
}
I worked with Writing and Reading a Texture once (for a scratching card).
You have to consider that when you change the Pixels of the Sprite, you are changing the pixels for the entire texture. So let's say that i change the pixel 1x1, most likely it will not change the pixel 1x1 in my sprite if i have a bunch of sprites in the same texture. So you have to consider the offsets of the sprite and reposition the pixel that you want to change.
Try to do something like this:
public void MouseClick()
{
Vector2 offset = new Vector2(XXX, YYY);
Vector2 mousePosition = Vector2.zero;
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
hitInfo = Physics2D.Raycast(mousePosition, Vector2.zero);
if (hitInfo)
{
spriteRendererComponent.sprite.texture.SetPixel((int)hitInfo.point.x + offset.x, (int)hitInfo.point.y + offset.y, zeroAlpha);
spriteRendererComponent.sprite.texture.Apply();
}
}
I created a object in unity
GameObject monsterclone =
(GameObject)Instantiate(monsterPrefab, floorPosition, Quaternion.identity);
This object should move in a wave style from a limit1 to limit2.
Then move back from limit2 to limit1.
Y position as well x position have to change in a specific way.
Vector3 nPos = mfloorPos + new Vector3(2f, 0f, 0f);
Vector3 oPos = mfloorPos + new Vector3(-2f, 0f, 0f);
How can I do it?
I can't exactly write the code without knowing more specific but i think this question is already asked any this link will help you out MOVE OBJECT as wave
EDIT:
I think the flat up and float down functionality will work for you for moving one point to another
example:
var floatup;
function Start(){
floatup = false;
}
function Update(){
if(floatup)
floatingup();
else if(!floatup)
floatingdown();
}
function floatingup(){
transform.position.y += 0.3 * Time.deltaTime;
yield WaitForSeconds(1);
floatup = false;
}
function floatingdown(){
transform.position.y -= 0.3 * Time.deltaTime;;
yield WaitForSeconds(1);
floatup = true;
}
example taken from
float amplitudeX = -25.0f;
float amplitudeY = 5.0f;
float omegaX = 0.5f;
float omegaY = 4.0f;
float index;
void Update () {
index += Time.deltaTime;
float x = amplitudeX*Mathf.Cos (omegaX*index);
float y = Mathf.Abs (amplitudeY*Mathf.Sin (omegaY*index));
if(transform.position.x > 24){
transform.eulerAngles = new Vector3(270, -90, 0);
}
if(transform.position.x < -24){
transform.eulerAngles = new Vector3(270, 90, 0);
}
transform.localPosition= new Vector3(x,y,20);
}
If this is a consitant wave and not dependant on speed I would use an animation to create a literal wave curve of the Position.Y value (much in the same principle as Ravindra Shekhawat has explained.) you can find out more about animation here.
Here is some code (untested) that you could go off. It is in c# so I hope it proves no issue with putting in to JavaScript.
bool monsterMoving = false;
void Update(){
//check monster moving to start updating position
if(monsterMoving == true){
//moving animation controls up and down "wave" movement
animation.CrossFade('moving');
//Lerp changes position
Transform.Lerp(transform.Position, oPos, Time.deltaTime);
if (transform.Position == oPos) {
//We are at destination, stop movement
monsterMoving = false;
}
} else {
// if monster stopped moving, return to idle animation (staying still)
animation.CrossFade('idle');
}
}
// function to send a new position to the monster object
void MoveTo(Vector3 newPos){
oPos = newPos;
monsterMoving = true;
}