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(); 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(); _chalkCollider = chalk.GetComponent(); 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(); _chalkCollider = towel.GetComponent(); 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; } }