initial commit
This commit is contained in:
192
Assets/Scripts/ChalkDrawer.cs
Normal file
192
Assets/Scripts/ChalkDrawer.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ChalkDrawer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Camera _camera;
|
||||
[SerializeField] private RenderTexture _boardTexture;
|
||||
[SerializeField] private float _brushSize = 0.02f;
|
||||
[SerializeField] private float _eraserSize = 0.05f;
|
||||
[SerializeField] private Color _chalkColor = Color.white;
|
||||
[SerializeField] private float _holdDistance = 1.5f;
|
||||
[SerializeField] private float _followSpeed = 12f;
|
||||
|
||||
public bool IsHoldingChalk => _holdingChalk;
|
||||
|
||||
private bool _holdingChalk = false;
|
||||
private bool _isErasing = false;
|
||||
private GameObject _chalkObject = null;
|
||||
private Rigidbody _chalkRb = null;
|
||||
private Collider _chalkCollider = null;
|
||||
private Texture2D _drawTexture;
|
||||
private bool _textureReady = false;
|
||||
private Vector3 _originalPosition;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
InitTexture();
|
||||
}
|
||||
|
||||
private void InitTexture()
|
||||
{
|
||||
if (_boardTexture == null) return;
|
||||
|
||||
_drawTexture = new Texture2D(_boardTexture.width, _boardTexture.height, TextureFormat.RGBA32, false);
|
||||
|
||||
Color[] pixels = new Color[_boardTexture.width * _boardTexture.height];
|
||||
for (int i = 0; i < pixels.Length; i++)
|
||||
pixels[i] = Color.black;
|
||||
_drawTexture.SetPixels(pixels);
|
||||
_drawTexture.Apply();
|
||||
|
||||
Graphics.Blit(_drawTexture, _boardTexture);
|
||||
|
||||
GameObject board = GameObject.FindGameObjectWithTag("Board");
|
||||
if (board != null)
|
||||
{
|
||||
MeshRenderer boardRenderer = board.GetComponent<MeshRenderer>();
|
||||
if (boardRenderer != null)
|
||||
boardRenderer.material.mainTexture = _boardTexture;
|
||||
}
|
||||
|
||||
_textureReady = true;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_holdingChalk) return;
|
||||
|
||||
HandleHolding();
|
||||
HandleDrawing();
|
||||
|
||||
if (Input.GetMouseButtonDown(1))
|
||||
DropChalk();
|
||||
}
|
||||
|
||||
public void PickupChalk(GameObject chalk)
|
||||
{
|
||||
_originalPosition = chalk.transform.position;
|
||||
_chalkObject = chalk;
|
||||
_chalkRb = chalk.GetComponent<Rigidbody>();
|
||||
_chalkCollider = chalk.GetComponent<Collider>();
|
||||
|
||||
if (_chalkRb != null)
|
||||
{
|
||||
_chalkRb.useGravity = false;
|
||||
_chalkRb.velocity = Vector3.zero;
|
||||
_chalkRb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
if (_chalkCollider != null)
|
||||
_chalkCollider.enabled = false;
|
||||
|
||||
_isErasing = false;
|
||||
_holdingChalk = true;
|
||||
}
|
||||
|
||||
public void PickupTowel(GameObject towel)
|
||||
{
|
||||
_originalPosition = towel.transform.position;
|
||||
_chalkObject = towel;
|
||||
_chalkRb = towel.GetComponent<Rigidbody>();
|
||||
_chalkCollider = towel.GetComponent<Collider>();
|
||||
|
||||
if (_chalkRb != null)
|
||||
{
|
||||
_chalkRb.useGravity = false;
|
||||
_chalkRb.velocity = Vector3.zero;
|
||||
_chalkRb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
if (_chalkCollider != null)
|
||||
_chalkCollider.enabled = false;
|
||||
|
||||
_isErasing = true;
|
||||
_holdingChalk = true;
|
||||
}
|
||||
|
||||
private void HandleHolding()
|
||||
{
|
||||
if (_chalkObject == null) return;
|
||||
|
||||
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
|
||||
Vector3 targetPos = ray.origin + ray.direction * _holdDistance;
|
||||
|
||||
_chalkObject.transform.position = Vector3.Lerp(
|
||||
_chalkObject.transform.position,
|
||||
targetPos,
|
||||
Time.deltaTime * _followSpeed
|
||||
);
|
||||
}
|
||||
|
||||
private void HandleDrawing()
|
||||
{
|
||||
if (!_textureReady) return;
|
||||
|
||||
if (Input.GetMouseButton(0))
|
||||
{
|
||||
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
|
||||
if (Physics.Raycast(ray, out RaycastHit hit))
|
||||
{
|
||||
if (hit.collider.CompareTag("Board"))
|
||||
DrawOnTexture(hit.textureCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawOnTexture(Vector2 uv)
|
||||
{
|
||||
Color paintColor = _isErasing ? Color.black : _chalkColor;
|
||||
float size = _isErasing ? _eraserSize : _brushSize;
|
||||
|
||||
int x = (int)(uv.x * _drawTexture.width);
|
||||
int y = (int)(uv.y * _drawTexture.height);
|
||||
int radius = Mathf.Max(1, (int)(size * _drawTexture.width));
|
||||
|
||||
for (int i = -radius; i <= radius; i++)
|
||||
{
|
||||
for (int j = -radius; j <= radius; j++)
|
||||
{
|
||||
if (i * i + j * j <= radius * radius)
|
||||
{
|
||||
int px = Mathf.Clamp(x + i, 0, _drawTexture.width - 1);
|
||||
int py = Mathf.Clamp(y + j, 0, _drawTexture.height - 1);
|
||||
_drawTexture.SetPixel(px, py, paintColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_drawTexture.Apply();
|
||||
Graphics.Blit(_drawTexture, _boardTexture);
|
||||
}
|
||||
|
||||
private void DropChalk()
|
||||
{
|
||||
if (_chalkObject == null) return;
|
||||
|
||||
if (_chalkRb != null)
|
||||
{
|
||||
_chalkRb.useGravity = false;
|
||||
_chalkRb.velocity = Vector3.zero;
|
||||
_chalkRb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
_chalkObject.transform.position = _originalPosition;
|
||||
|
||||
if (_chalkRb != null)
|
||||
{
|
||||
_chalkRb.useGravity = true;
|
||||
_chalkRb.WakeUp();
|
||||
}
|
||||
|
||||
if (_chalkCollider != null)
|
||||
_chalkCollider.enabled = true;
|
||||
|
||||
_holdingChalk = false;
|
||||
_isErasing = false;
|
||||
_chalkObject = null;
|
||||
_chalkRb = null;
|
||||
_chalkCollider = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user