How to Instantiate circles all over the canvas unity(Mandelbrot set) - c#

i am trying to Make The Mandelbrot set, i have the function thing working, zn = zn^
and i want to Visualizing the Mandelbrot set using circles, i tried this code but it cruses every time i compile, here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PaintMand : MonoBehaviour
{
[SerializeField] private GameObject CirclePaint;
[SerializeField] private RectTransform RedCircle;
[SerializeField] private Canvas canvas;
private float sumDistance = 0;
private bool HasFinshed = false;
private Vector2 start = new Vector2(2.133f,0.976f);
private void Update()
{
if (!HasFinshed)
{
sumDistance = AutoAxis.GetSumDistance();
MoveRed();
LoadRed();
}
}
public void MoveRed()
{
if(start.y < -0.988f)
{
HasFinshed = true;
}
else if(start.x <= -2.107f)
{
start.x = 2.133f;
start.y -= 0.20f;
}
else
{
start.x -= 0.20f;
}
RedCircle.anchoredPosition = start;
}
public void LoadRed()
{
if (IsUnstable())
{
GameObject NewCircle = Instantiate(CirclePaint, Vector3.zero,Quaternion.identity);
NewCircle.GetComponent<Image>().color = new Color(sumDistance,sumDistance,sumDistance);
NewCircle.transform.SetParent(canvas.transform);
NewCircle.GetComponent<RectTransform>().anchoredPosition = RedCircle.anchoredPosition;
}
}
private bool IsUnstable()
{
if(sumDistance > 1000)
{
return true;
}
return false;
}
}
the red circle is the c in the equation, zn = zn^ + c
and it moves every frame and checks if its unstable(the autoaxis is the class that makes the Visualizing the function) it gets the sum of the distance between all the circles and sends the float to the paintmad class, this cruses every time, pls help :(

Related

Object don't exclude from list

Me need exclude object from the list, i make it as other variants, but it don't work? Why?
I make destroy block as minecraft, but i can see just no thing =/ and i make as can doing.
Code:
using System.Collections.Generic;
using System.Collections;
using UnityEngine;
public class GetTarget : MonoBehaviour
{
[Header("Координаты блока")] // positions blocks
public int positionX;
public int positionY;
public int positionZ;
[Header("Получение цели")] // get target
public static List<GameObject> target = new List<GameObject>();
private void OnTriggerStay(Collider collider) // check on touch to trigger
{
if(collider.gameObject.name == "WorldMap") { return; }
else if(collider.gameObject.name == "Water") { return; }
else if(collider.gameObject.name == "Berries") { return; } // this details in the code don't work now.
else
{
target.Insert(0, collider.gameObject);
Debug.Log("Вы получили " + target[0]); // Вы получите = You can have target[0] now
}
}
private void Update() // set round position
{
Vector3 positions = transform.position;
positionX = (int)Mathf.Round(gameObject.transform.position.x);
positionY = (int)Mathf.Round(gameObject.transform.position.y);
positionZ = (int)Mathf.Round(gameObject.transform.position.z);
positions.x = positionX;
positions.y = positionY;
positions.z = positionZ;
}
}
Thank you to everyone!

My if statement is On constant use and doesn't do the statement

So I have Ctr C Ctr V an Interaction System from YT channel.
I have perfectly copied line by line But the only issue was that he was using the old input system and used KeyPressedDown and keyPressedUp to make 2 boolean's which change according what state is the keypressed, I tried to mimic it with new Input system by making it from a button to a Axis value which follows the logic of if its ClickedAxis>0.4 its true and ClockedAxis==0 false, as a quick press it worked so I was happy BUT here comes the bug
My if statement is Being Spammed Constantly like none stop. My statement basically say's that if the Interacting is true Do :
bool interacting;
If(interacting)
{
float HoldingDownTimer+=Time.DeltaTime;
if(HoldingDownTimer>=5)
{
//Do your task;
}
}
but When I run the statement For some reason it prints 0.0110823 values which are stuck at that range of number's no lower no higher, My theory is that its been spam called.
Here's the Script
If your interested for all the components the YT channel is this guy's VeryHotShark
using UnityEngine;
using NaughtyAttributes;
public class LocomotionScript : MonoBehaviour
{
#region Data
[BoxGroup("Animation Handling Data")]
Animator animator;
int isWalkingHash;
[SerializeField] bool movementPressed;
[BoxGroup("Input Handling Data")]
private CharacterController controller;
public MovementInput input;
Vector2 currentMovement;
[SerializeField] float speed = 1;
private Vector3 velocity;
private float gravity = -9.81f;
public Transform ground;
public float distanceToGround = 0.4f;
public LayerMask groundMask;
private Vector2 smoothinMovement;
private float smoothInputSpeed;
private Vector2 tempCurrentMovement;
private bool isGrounded;
public InteractionInputData interactionInput;
#endregion
private void Awake()
{
animator = GetComponent<Animator>();
input = new MovementInput();
controller = GetComponent<CharacterController>();
input.KeyBoard.ASWD.performed += ctx =>
{
currentMovement = ctx.ReadValue<Vector2>();
movementPressed = currentMovement.x != 0 || currentMovement.y != 0;
};
}
private void Start()
{
interactionInput.Reset();
}
void GetInteractionInputData()
{
interactionInput.InteractedClicked = input.KeyBoard.Interact.ReadValue<float>() > 0.1f;
interactionInput.InteractedReleased = input.KeyBoard.Interact.ReadValue<float>() == 0f;
}
private void Update()
{
LocoMotion();
Grav();
Interact();
GetInteractionInputData();
}
void Grav()
{
isGrounded = Physics.CheckSphere(ground.position, distanceToGround, groundMask);
if (isGrounded && velocity.y<0)
{
velocity.y = -2f;
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
void Interact()
{
}
void LocoMotion()
{
tempCurrentMovement=Vector2.SmoothDamp(tempCurrentMovement, currentMovement, ref smoothinMovement, smoothInputSpeed);
Vector3 movement = (tempCurrentMovement.y * transform.forward) + (tempCurrentMovement.x * transform.right);
WalkAnimation();
controller.Move(movement * speed * Time.deltaTime);
}
void WalkAnimation()
{
animator.SetBool("WalkingHush", movementPressed);
}
private void OnEnable()
{
input.KeyBoard.ASWD.Enable();
input.KeyBoard.Interact.Enable();
}
private void OnDisable()
{
input.KeyBoard.ASWD.Enable();
input.KeyBoard.Interact.Enable();
}
}
//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace th
{
public class InteractionController : MonoBehaviour
{
#region Variables
[Header("Data")]
public InteractionData interactionData;
public InteractionInputData interactionInputData;
[Space]
[Header("RaySetting's")]
public float rayDistance;
public float raySphereRadius;
public LayerMask interactableLayer;
#endregion
#region Private
private Camera m_cam;
private bool m_interacting;
private float m_holderTimer = 0.0f;
#endregion
#region BuildIn
private void Awake()
{
m_cam = FindObjectOfType<Camera>();
}
private void Update()
{
CheckForInteractable();
CheckForInteractableInput();
}
#endregion
#region Crafted Methodds
void CheckForInteractable()
{
Ray _ray = new Ray(m_cam.transform.position, m_cam.transform.forward);
RaycastHit _hitInfo;
bool _hitSomething = Physics.SphereCast(_ray, raySphereRadius, out _hitInfo,
rayDistance,interactableLayer);
if (_hitSomething)
{
InteractableBase _interactable = _hitInfo.transform.GetComponent<InteractableBase>();
if (_interactable != null)
{
if (interactionData.isEmpty())
{
interactionData.Interactable = _interactable;
}
else
{
if (!interactionData.IsSameInteractible(_interactable))
interactionData.Interactable = _interactable;
}
}
}
else
{
interactionData.ResetData();
}
Debug.DrawRay(_ray.origin, _ray.direction * rayDistance, _hitSomething ? Color.green : Color.red);
}
void CheckForInteractableInput()
{
if (interactionData.isEmpty())
{
return;
}
if (interactionInputData.InteractedClicked)
{
m_interacting = true;
m_holderTimer = 0f;
}
if (interactionInputData.InteractedReleased)
{
m_interacting = false;
m_holderTimer = 0f;
}
if (m_interacting)
{
if (!interactionData.Interactable.IsInteractible)
return;
if (interactionData.Interactable.HoldInteract)
{
m_holderTimer += Time.deltaTime;
Debug.Log(m_holderTimer);
if (m_holderTimer >= interactionData.Interactable.holdDuration)
{
interactionData.Interact();
m_interacting = false;
}
}
else
{
interactionData.Interact();
m_interacting = false;
}
}
}
#endregion
}
}
///
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th
{
[CreateAssetMenu(fileName ="Interaction Data",menuName = "InteractionSystem/InteractionData")]
public class InteractionData : ScriptableObject
{
private InteractableBase m_interactible;
public InteractableBase Interactable
{
get => m_interactible;
set => m_interactible = value;
}
public void Interact()
{
m_interactible.OnInteract();
ResetData();
}
public bool IsSameInteractible(InteractableBase _newInteractible) => m_interactible == _newInteractible;
public bool isEmpty() => m_interactible == null;
public void ResetData()=> m_interactible = null;
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "InteractionInputData", menuName = "InteractionSystem/InputData")]
public class InteractionInputData : ScriptableObject
{
private bool m_interactedClicked;
private bool m_interactRelease;
public bool InteractedClicked
{
get => m_interactedClicked;
set => m_interactedClicked = value;
}
public bool InteractedReleased
{
get => m_interactRelease;
set => m_interactRelease = value;
}
public void Reset()
{
m_interactedClicked = false;
m_interactRelease = false;
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th
{
public interface IInteractible
{
float HoldDurration { get; }
bool HoldInteract { get; }
bool MultipleUse { get;}
bool IsInteractible { get; }
void OnInteract();
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th{
public class InteractableBase : MonoBehaviour,IInteractible
{
#region Variables
[Header("Interactible Settings")]
public float holdDuration;
[Space]
public bool holdInteract;
public bool multipleUse;
public bool isInteractible;
#endregion
#region Properties
public float HoldDurration => holdDuration;
public bool HoldInteract => holdInteract;
public bool MultipleUse => multipleUse;
public bool IsInteractible => isInteractible;
#endregion
#region Methods
public void OnInteract()
{
Debug.Log("Interacted: " + gameObject.name);
}
#endregion
}
}
Well without parsing through your entire code:
once
HoldingDownTimer >= 5
is true you still keep adding more time in the next frame so the condition is still true in the next frame => you will keep calling it all the following frames as well.
You could introduce a flag somewhat like e.g.
private bool alreadyCalled;
and then
if(interacting)
{
if(!alreadyCalled)
{
HoldingDownTimer += Time.DeltaTime;
if(HoldingDownTimer >= 5)
{
alreadyCalled = true;
//Do your task;
}
}
}
else
{
alreadyCalled = false;
}
As far as I understood your code I think:
I found the issue in it actually you are checking if the 'm_holdTimer' >= 'holdDuration' then perform interaction and you are making it equal to 0 on click start and click end.
So it means if the player has continuously held the button then it will not reset 'm_holdTimer'... so it will continue to call the function recursively because player hasn't actually ended the click so there is not any single function which is reseting 'm_holdTimer' to 0. still if you didn't get my point just copy this function and paste it instead of your own and see if it works, if it do work then you can check the difference between line of code then you'll understand it for sure.
void CheckForInteractableInput()
{
if (interactionData.isEmpty())
{
return;
}
if (interactionInputData.InteractedClicked)
{
m_interacting = true;
m_holderTimer = 0f;
}
if (interactionInputData.InteractedReleased)
{
m_interacting = false;
m_holderTimer = 0f;
}
if (m_interacting)
{
if (!interactionData.Interactable.IsInteractible)
return;
if (interactionData.Interactable.HoldInteract)
{
m_holderTimer += Time.deltaTime;
Debug.Log(m_holderTimer);
if (m_holderTimer >= interactionData.Interactable.holdDuration)
{
m_holderTimer = 0f;
interactionData.Interact();
m_interacting = false;
}
}
else
{
interactionData.Interact();
m_interacting = false;
}
}
}
Hope it helps... Happy coding :)

Unity exploded view script does not seem to work but is also not turning up any errors

I have been working with some script which is supposed to cause the childmeshes of an object move away from their center by a certain distance on wake, Unfortunately while I am not getting any errors, the script also doesnt seem to work no matter what values I adjust. I tried to debug but am still struggling a bit, Any advice would be appreciated.
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Interactions
{
public class ExplodedViewPart
{
public Vector3 StartPosition { get; }
public Vector3 Destination;
public float MoveDistance
{
set => Destination = m_meshCenter * value;
}
private readonly Vector3 m_meshCenter;
public ExplodedViewPart(Vector3 startPosition, Vector3 meshCenter, float moveDistance)
{
m_meshCenter = meshCenter;
StartPosition = startPosition;
Destination = meshCenter * moveDistance;
}
}
public class ExplodedView : MonoBehaviour
{
[Range(0.0f, 1.0f)]
[SerializeField] private float m_percentage;
[SerializeField] private float m_moveDistance = 3f;
private float m_oldMoveDistance = 3f;
private readonly List<ExplodedViewPart> m_parts = new List<ExplodedViewPart>();
private readonly List<Transform> m_partTransforms = new List<Transform>();
private void Awake()
{
foreach (var component in GetComponentsInChildren<MeshRenderer>())
{
Transform partTransform = component.transform;
m_partTransforms.Add(partTransform);
m_parts.Add(new ExplodedViewPart(partTransform.position, component.bounds.center, m_moveDistance));
}
}
private void ChangeMaxDistance(float value)
{
for (int i = 0; i < m_partTransforms.Count; i++)
{
m_parts[i].MoveDistance = value;
}
}
private void OnValidate()
{
if (Math.Abs(m_oldMoveDistance - m_moveDistance) > float.Epsilon)
{
ChangeMaxDistance(m_moveDistance);
m_oldMoveDistance = m_moveDistance;
}
Explode(m_percentage);
}
public void Explode(float percentage)
{
for (int i = 0; i < m_partTransforms.Count; i++)
{
m_partTransforms[i].position = (1 - percentage) * m_parts[i].StartPosition +
percentage * m_parts[i].Destination;
}
}
}
}

How to lerp between two animation curves so it will play the first animation curve in the array and when it ends, it start playing the second?

In this case there are two animation curves in the array. One for fade in one for fade out.
Currently I'm using the index 1 in the array but I want to lerp smooth between index 0 and index 1 so it will fade in and fade out nonstop smooth.
I want to play animation curve at index 0 when it finish to start play the second animation curve at index 1.
I tried to use a for loop before like this:
for (int i = 0; i < fadeIn.Length; i++)
{
_renderer.material.SetFloat(shaderProperty, fadeIn[i].Evaluate(Mathf.InverseLerp(0, spawnEffectTime, timer)));
}
but it didn't change between the animation curves.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnEffect : MonoBehaviour {
public float spawnEffectTime = 2;
public float pause = 1;
public AnimationCurve[] fadeIn;
public bool fadeOut = false;
ParticleSystem ps;
float timer = 0;
Renderer _renderer;
int shaderProperty;
void Start ()
{
shaderProperty = Shader.PropertyToID("_cutoff");
_renderer = GetComponent<Renderer>();
ps = GetComponentInChildren <ParticleSystem>();
var main = ps.main;
main.duration = spawnEffectTime;
ps.Play();
}
void Update()
{
FadeIn();
}
private void FadeOut()
{
}
private void FadeIn()
{
if (timer < spawnEffectTime + pause)
{
timer += Time.deltaTime;
}
else
{
ps.Play();
timer = 0;
}
_renderer.material.SetFloat(shaderProperty, fadeIn[1].Evaluate(Mathf.InverseLerp(0, spawnEffectTime, timer)));
}
}
This is what I was looking for. Working great.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnEffect : MonoBehaviour
{
public float spawnEffectTime = 2;
public float pause = 1;
public AnimationCurve[] fadeIn;
public bool fadeOut = false;
ParticleSystem ps;
float timer = 0;
Renderer _renderer;
int fadeIndex = 0;
int shaderProperty;
void Start()
{
shaderProperty = Shader.PropertyToID("_cutoff");
_renderer = GetComponent<Renderer>();
ps = GetComponentInChildren<ParticleSystem>();
var main = ps.main;
main.duration = spawnEffectTime;
ps.Play();
}
void Update()
{
FadeIn();
}
private void FadeOut()
{
}
private void FadeIn()
{
if (timer < spawnEffectTime + pause)
{
timer += Time.deltaTime;
}
else
{
ps.Play();
timer = 0;
if (fadeIndex == 0)
{
fadeIndex = 1;
}
else
{
fadeIndex = 0;
}
}
_renderer.material.SetFloat(shaderProperty, fadeIn[fadeIndex].Evaluate(Mathf.InverseLerp(0, spawnEffectTime, timer)));
}
}

c# Unity - Mutiplayer interacting with objects

using UnityEngine;
using UnityEngine.Networking;
public class Interactable : NetworkBehaviour {
public float radius = 2f;
bool isFocus = false;
Transform player;
bool hasInteracted = false;
public Transform interactionPoint;
public virtual void Interact()
{
// This method is meant to be overwritten
Debug.Log("Interacting with " + transform.name);
}
private void Update()
{
if (isFocus && !hasInteracted)
{
float distance = Vector3.Distance(player.position, interactionPoint.position);
if(distance <= radius)
{
Interact();
hasInteracted = true;
}
}
}
public void onFocused(Transform Player)
{
isFocus = true;
player = Player;
}
public void onDeFocused()
{
isFocus = false;
player = null;
hasInteracted = false;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, radius);
}
}
This is for the interaction which is overwritten.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class SphereBehaviour : Interactable {
public float countdown = 1;
public float timeLeft = 5f;
public override void Interact()
{
Debug.Log("Interacting with the Sphere object");
StartCoroutine(StartCountdown());
}
public IEnumerator StartCountdown() // Countdown from 5
{
countdown = timeLeft;
while (countdown > 0)
{
yield return new WaitForSeconds(1.0f);
countdown--;
}
}
The Problem is that this isn't networked and I can't think of the logic to do it. An Interface won't work or anything. Is there any possible solution which doesn't require changing everything?
I'm just trying to turn Brackeys set of youtube tutorials to something multiplayer.
I'm assuming you're using the public "countdown" variable for some UI element.
If you want each player to see their own countdown when they themselves touch this Sphere, this should work fine.
If anyone touching the sphere should trigger a countdown for everyone, then this will have to be done differently. You'll want the host/server to track interactions between players and spheres, then trigger the countdown coroutine in the clients.
I personally don't recommend #1 in any case, as collisions/interactions should be done server-side.

Categories

Resources