Face and Move Toward Player.

Good Morning All,

I am not a programming expert by any stretch of the imagination, but if there is one thing I know it’s that getting the code to work is the first step and optimizing is the second step.

With that being said I have decided to share all the code I am using for my current project and hope it can help someone or someone can help me make it better. Regardless, the game I am working on is a Platformer/RPG so there will be a lot of systems happening.

The first code piece I would like to share is the MoveTowardPlayer script that determines if the player is on the Left or Right of whatever GameObject this script is attached to and will move the host toward the player. If the player crosses its path, the enemy will flip its X-Axis to face the player.

 

http://https://www.youtube.com/watch?v=Xnjr70xMORQ&feature=youtu.be

Below is the script I use to accomplish this effect. 

[sourcecode language=”csharp”]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveTowardPlayer : MonoBehaviour {

public Transform target;
public float speed;

private void Start()
{

//This finds the GameObject that has the PlayerController script attached.
//This is assuming there is only one PlayerController.
target = FindObjectOfType<PlayerController>().transform;
}

void Update()
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);

#region \/—–Face Right—–\/
if(transform.position.x < target.position.x)
{
GetComponent<SpriteRenderer>().flipX = true;
}
#endregion
#region \/—–Face Left—–\/
else if(transform.position.x > target.position.x)
{
GetComponent<SpriteRenderer>().flipX = false;
}
#endregion
}
}
[/sourcecode]

***As of 04/13/18, this is the current script I am using. If I update it I will update this post.***

 

Castlevania Style – Following Shadow

Hello All,

I just wanted to share a code snippet I found while searching the internet for some assistance.

In my game, I was thinking of having some trailing shadows like in Castlevania when a special magic spell is activated. Well, I was having a doozy of a time trying to get it to work so I did a search and found that my issue was already solved and the answer was shared with the public. I thought it would be nice to see the solution and give credit where credit is due.

The effect I was trying to achieve was the trailing shadows shown here 

The solution was given by a user named jeffreyschoch in the Unity forums.

[sourcecode language=”csharp”]
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SpriteAfterImage : MonoBehaviour {
[Tooltip("The color each after-image will fade to over its lifetime. Alpha of 0 is recommended")]
public Color finalColor = Color.clear;
[Tooltip("The amount of time an after-image will take to fade away.")]
public float trailLifetime = .25f;
[Tooltip("The distance this object must move to spawn one after-image.")]
public float distancePerSpawn = .1f;
[Tooltip("Optimization – number of after-images to create before the effect starts, to reduce the start-up load.")]
public int spawnOnStart = 0;
private SpriteRenderer mainSpriteRenderer; // the sprite renderer to trail after
private List<SpriteRenderer> readyObjects; // the list of objects ready to be shown
private float distanceTraveledSinceLastSpawn; // the distance this object has moved since the last object was shown
private Vector3 lastSpawnPosition; // the position the last object was spawned
private Color initialColor;
private void Awake() {
// get the sprite renderer on this object
mainSpriteRenderer = GetComponent<SpriteRenderer>();
initialColor = mainSpriteRenderer.color;
// initialize the empty list
readyObjects = new List<SpriteRenderer>();
// optionally populate list beforehand with objects to use
for(int i = 0; i < spawnOnStart; i++) {
readyObjects.Add(makeSpriteObject());
}
}
private void OnEnable() {
StartCoroutine(trailCoroutine());
}
// function to create a sprite gameobject ready for use
private SpriteRenderer makeSpriteObject() {
// create a gameobject named "TrailSprite" with a SpriteRenderer component
GameObject spriteObject = new GameObject("TrailSprite", typeof(SpriteRenderer));
// parent the object to this object so that it follows it
spriteObject.transform.SetParent(transform);
// center it on this object
spriteObject.transform.localPosition = Vector3.zero;
// hide it
spriteObject.SetActive(false);
return spriteObject.GetComponent<SpriteRenderer>();
}
private IEnumerator trailCoroutine() {
// keep running while this component is enabled
while(enabled) {
// get the distance between the current position and the last position
// a trail object was spawned
distanceTraveledSinceLastSpawn = Vector2.Distance(lastSpawnPosition, transform.position);
// if that distance is greater than the specified distance per spawn
if(distanceTraveledSinceLastSpawn > distancePerSpawn) {
// if there aren’t any objects ready to show, spawn a new one
if(readyObjects.Count == 0) {
// add that object’s sprite renderer to the trail list
readyObjects.Add(makeSpriteObject());
}
// get the next object in the ready list
SpriteRenderer nextObject = readyObjects[0];
// set this trailSprite to reflect the current player sprite
nextObject.sprite = mainSpriteRenderer.sprite;
// this makes it so that the trail will render behind the main sprite
nextObject.sortingLayerID = mainSpriteRenderer.sortingLayerID;
nextObject.sortingOrder = mainSpriteRenderer.sortingOrder – 1;
// set it loose in the world
nextObject.transform.SetParent(null, true);
// match the copy’s scale to the sprite’s world-space scale
nextObject.transform.localScale = mainSpriteRenderer.transform.lossyScale;
// show it
nextObject.gameObject.SetActive(true);
// start it fading out over time
StartCoroutine(fadeOut(nextObject));
// remove it from the list of ready objects
readyObjects.Remove(nextObject);
// save this position as the last spawned position
lastSpawnPosition = transform.position;
// reset the distance traveled
distanceTraveledSinceLastSpawn = 0;
}
// wait until next frame to continue the loop
yield return null;
}
// reduce number of sprites back to original pool size
foreach(SpriteRenderer sprite in this.readyObjects) {
if(this.readyObjects.Count > spawnOnStart) {
Destroy(sprite.gameObject);
} else {
resetObject(sprite);
}
}
}
private IEnumerator fadeOut(SpriteRenderer sprite) {
float timeElapsed = 0;
// while the elapsed time is less than the specified trailLifetime
while(timeElapsed < trailLifetime) {
// get a number between 0 and 1 that represents how much time has passed
// 0 = no time has passed, 1 = trailLifetime seconds has passed
float progress = Mathf.Clamp01(timeElapsed / trailLifetime);
// linearly interpolates between the initial color and the final color
// based on the value of progress (0 to 1)
sprite.color = Color.Lerp(initialColor, finalColor, progress);
// track the time passed
timeElapsed += Time.deltaTime;
// wait until next frame to continue the loop
yield return null;
}
// reset the object so that it can be reused
resetObject(sprite);
}
// resets the object so that it is ready to use again
private void resetObject(SpriteRenderer sprite) {
// hide the sprite
sprite.gameObject.SetActive(false);
// reset the tint to default
sprite.color = initialColor;
// parent it to this object
sprite.transform.SetParent(transform);
// center it on this object
sprite.transform.localPosition = Vector3.zero;
// add it to the ready list
readyObjects.Add(sprite);
}
}
[/sourcecode]

You can find the original article located here: https://forum.unity.com/threads/shadow-clones-castlevania-style-2d.482427/