/** * take in spray paint from the player with a distribution around the centermost * hitpoint (the first hitpoint). hitpoints should be a normalized vector where * (0,0,z) represents the bottom left and (1,1,z) is the top right. z is not used. */ public void Spray(PlayerSprayData playerSprayData) { Vector2Int[] binsHit = new Vector2Int[playerSprayData.sprayPoints.Length]; /* any ray which did not intersect the surface will have their bin set to (-1,-1) */ for (int i = 0; i < playerSprayData.sprayPoints.Length; ++i) { if (playerSprayData.castSuccess[i]) { binsHit[i] = new Vector2Int(Mathf.RoundToInt(playerSprayData.sprayPoints[i].x * sprayGridX), Mathf.RoundToInt(playerSprayData.sprayPoints[i].y * sprayGridY)); } else { binsHit[i] = new Vector2Int(-1, -1); } } for (int i = 0; i < binsHit.Length; ++i) { if (binsHit[i].x >= 0 && binsHit[i].x <= sprayGridX && binsHit[i].y >= 0 && binsHit[i].y <= sprayGridY) { // do stuff } } }
/** * If near a taggable surface and we have enough spray cans, spray graffiti * onto the taggable surface. If we were unable to spray the surface for any reason * we do not deduct any spray cans. */ void SprayTag() { if (nearestTagSurface != null && sprayCansCurrent > 0 && Input.GetButton("Fire3")) { /* * bool sprayed; * TaggableSurfaceController tagScript = nearestTagSurface.GetComponent<TaggableSurfaceController>(); * if (!tagScript.InGroup) * { * sprayed = tagScript.SprayTag(smallTag); * } * else * { * sprayed = tagScript.SprayTag(mediumTagPieces[tagScript.SurfaceIndex]); * } * * if (sprayed) * { * --sprayCansCurrent; * }*/ RayTagSurfaceController tagScript = nearestTagSurface.GetComponent <RayTagSurfaceController>(); GameObject surface = tagScript.getParent(); RaycastHit hitInfo = new RaycastHit(); Vector3[] castDirections = new Vector3[numRayCast]; /* get the direction of spraying, tending towards the centre of the surface * but constrained with a max angle that the player can spray at */ Vector3 toSurfaceCenter = surface.transform.position - transform.position; Debug.DrawRay(transform.position, toSurfaceCenter, Color.red); Debug.DrawRay(transform.position, surface.transform.forward, Color.blue); float angleDifference = Vector3.Angle(toSurfaceCenter, surface.transform.forward); if (angleDifference > sprayDirectionMaxAngle) { toSurfaceCenter = Vector3.RotateTowards(toSurfaceCenter, surface.transform.forward, Mathf.Deg2Rad * (angleDifference - sprayDirectionMaxAngle), 0.0f); } castDirections[0] = toSurfaceCenter; castDirections[1] = Quaternion.Euler(sprayConeAngle, 0, 0) * toSurfaceCenter; castDirections[2] = Quaternion.Euler(-sprayConeAngle, 0, 0) * toSurfaceCenter; castDirections[3] = Quaternion.Euler(0, sprayConeAngle, 0) * toSurfaceCenter; castDirections[4] = Quaternion.Euler(0, -sprayConeAngle, 0) * toSurfaceCenter; /* TODO: remove debug ray drawing when no longer necessary */ bool anyRayHit = false; Vector3[] castHitPoints = new Vector3[numRayCast]; BitArray castSuccess = new BitArray(numRayCast); for (int i = 0; i < numRayCast; ++i) { Debug.DrawRay(transform.position, castDirections[i], Color.green); if (Physics.Raycast(transform.position, castDirections[i], out hitInfo, 10f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Collide)) { anyRayHit = true; castHitPoints[i] = ((hitInfo.point - surface.transform.position).normalized + new Vector3(1, 1, 1)).normalized; castSuccess[i] = true; } else { castSuccess[i] = false; } } if (anyRayHit) { PlayerSprayData playerSprayData = new PlayerSprayData(castHitPoints, castSuccess, transform.position, this.mediumTag); tagScript.Spray(playerSprayData); } } }