I made a game where you peel apples. It paints to a mask texture to reveal the meat below the apples skin. It works just fine in the editor, but when I build the project for Win or WebGL the apple does not peel.
At the start the apple makes a copy of the mask texture and replaces it the mask with copy. The mask copy is created programmatically so the texture is set to readable/writable. I’m not sure what could be going on. Any insights would be appreciated.
Peeler Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PeelBrush : MonoBehaviour
{
public Transform anchor;
public Transform peelerTransform;
public Transform peelTransform;
public Texture2D mask;
public Texture2D peelerShape;
public Color[] peelPixels;
public int brushWidth, brushHeight;
public GameObject peelTemplate;
public GameObject peelObject;
public float blend;
public float blendX;
public float blendScale = 5;
public LayerMask layerMask;
Vector3 start;
// Start is called before the first frame update
void Start()
{
peelPixels = peelerShape.GetPixels();
brushWidth = peelerShape.width;
brushHeight = peelerShape.height;
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 mouse = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
Ray ray = Camera.main.ScreenPointToRay(mouse);
Debug.DrawRay(ray.origin, ray.direction);
bool hit = Physics.Raycast(ray, out RaycastHit hitData, float.MaxValue, layerMask);
if (hit)
{
transform.position = hitData.point + hitData.normal / 4;
transform.forward = -hitData.normal;
Debug.DrawRay(hitData.point, hitData.normal,Color.red);
Fruit fruit = null;
Transform parent = hitData.collider.transform.parent;
while (parent != null)
{
parent.TryGetComponent<Fruit>(out fruit);
if (fruit)
break;
parent = parent.parent;
}
if (Input.GetMouseButtonDown(0))
{
blendX = hitData.point.x;
start = hitData.point;
}
if (Input.GetMouseButton(0))
{
Material mat = hitData.collider.GetComponent<MeshRenderer>().material;
mask = (Texture2D)hitData.collider.GetComponent<MeshRenderer>().material.GetTexture("_MaskTex");
Vector2Int textureCoord = new Vector2Int((int)(mask.width * hitData.textureCoord.x), (int)(mask.height * hitData.textureCoord.y));
if (hitData.point.x - blendX < 0.1f)
{
if (!peelObject)
{
peelObject = GameObject.Instantiate(peelTemplate, peelerTransform.position, Quaternion.Euler(Vector3.right + Vector3.up + Vector3.forward));
peelObject.transform.parent = peelTransform;
}
if (fruit)
{
fruit.peeling = true;
}
Material mat2 = peelObject.GetComponentInChildren<MeshRenderer>().material;
blend += Mathf.Abs(hitData.point.x - blendX) / blendScale;
blendX = hitData.point.x;
mat2.SetFloat("_Blend", blend);
try
{
DrawCut(textureCoord.x - brushWidth / 2, textureCoord.y);
hitData.collider.GetComponent<MeshRenderer>().material.SetTexture("_MaskTex", mask);
}
catch (System.Exception e)
{
blend = 0;
peelObject.AddComponent<Rigidbody>();
peelObject = null;
}
}
}
if (Input.GetMouseButtonUp(0) || blend >= 1)
{
blend = 0;
peelObject.AddComponent<Rigidbody>();
peelObject = null;
if (fruit)
{
fruit.peeling = false;
}
}
}
else
{
transform.position = anchor.position;
transform.rotation= anchor.rotation;
}
}
void DrawPixel(int x, int y, Color color)
{
mask.SetPixel(x, y, color);
mask.Apply();
}
void DrawCut(int x, int y)
{
mask.SetPixels(x, y, brushWidth, brushHeight, peelPixels);
mask.Apply();
}
/* public float layers;
[Range(0.1f, 1f)]
public float step = 1/(2*Mathf.PI);
public float scale = 1;
private void OnDrawGizmos()
{
Gizmos.color = Color.green;
if (step < 0.08f)
step = 0.08f;
List<Vector3> points = new List<Vector3>();
for(float i = 0; i < 2* Mathf.PI; i += step)
{
float angle = scale * Mathf.Pow(1.1f, i);
Vector3 polarPoint = new Vector3(Mathf.Sin(angle),i,Mathf.Cos(angle));
Gizmos.DrawSphere(polarPoint,.1f);
points.Add(polarPoint);
}
for(int i =0; i < points.Count-1; i++)
{
Vector3 forward = (points[i+1]-points[i]).normalized;
Vector3 right = CalcRight(forward);
Vector3 up = CalcUp(right,forward);
Gizmos.color = Color.blue;
Gizmos.DrawRay(points[i], forward);
Gizmos.color = Color.green;
Gizmos.DrawRay(points[i], right);
Gizmos.color = Color.red;
Gizmos.DrawRay(points[i], up);
}
}
*/
public Vector3 CalcRight(Vector3 forward)
{
return Vector3.Cross(Vector3.up, forward);
}
public Vector3 CalcUp(Vector3 right, Vector3 forward)
{
return -Vector3.Cross(right, forward);
}
}
Fruit/Apple Code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fruit : MonoBehaviour
{
public MeshRenderer meshRenderer;
public Material mat;
public Texture2D mask;
public MeshRenderer eyeRenderer;
public Material eyeMat;
public Texture normal, wince, dead;
public MeshRenderer mouthRenderer;
public Material mouthMat;
public Texture smile, oh, frown,deadMouth;
public bool peeling,witnessing,selected,alive=true;
public float peelPercentage;
public float deadPercent =.70f;
Animator animator;
// Start is called before the first frame update
void Start()
{
mat = meshRenderer.material;
mask = (Texture2D)Instantiate(mat.GetTexture("_MaskTex"));
mat.SetTexture("_MaskTex", mask);
eyeMat = eyeRenderer.material;
mouthMat= mouthRenderer.material;
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (peeling && alive)
{
UpdatePercentage();
alive = peelPercentage > deadPercent;
}
if(peeling && alive)
{
eyeMat.mainTexture = wince;
mouthMat.mainTexture = oh;
}
else if (alive)
{
eyeMat.mainTexture = normal;
if (peelPercentage == 0 || peelPercentage > 98f)
mouthMat.mainTexture = smile;
else
mouthMat.mainTexture = frown;
}
animator.SetBool("peeling",peeling);
}
void UpdatePercentage()
{
int totalWhite = 0;
float total = 0;
int density = mask.width * mask.height;
Color[] colors = mask.GetPixels(0);
foreach(Color k in colors)
{
float color = k.r + k.g + k.b;
color /= 3;
total += color;
bool white = color > .8f; ;
if (white)
{
totalWhite++;
}
}
peelPercentage = total / colors.Length;
}
}
Here’s the game:
Also lemme know what you think it, if you don’t mind.