Hoax News

Hello everyone,

I would like to announce the development of Hoax News!
Hoax News is a 2.5D + 3D Action Game about Conspiracy Theories.


Download the playable teaser T0.1: HoaxNewsT01.zip - Google Drive

Or play the demo directly in WebGL: https://hoax-news-game.web.app/

Key Points:
• Rendering Pipeline: URP
• Unity Version: 2021 (will be moved to 2022 during development)
• Estimated Release Date: Q2 2023
• Target Playtime: ~2h
• Target Framerate: > 60 FPS on avarage gaming PCs
• Final Game Release: Steam

Character Controller Features:
• 2.5D + 3D Support
• Run (WASD)
• Walk (CTRL)
• Jump / Double Jump (Space)
• Dodge (Shift)
• Melee Attack (Left Mouse Button)
• Throw Axe Attack (Right Mouse Button)
• Shoot Gun(s) (Middle Mouse Button)
• Vault
• Ledge Climbing
• Moving Platform Support
• Slide Down Steep Slopes Support
• Foot IK (iStep)
• Aim IK
• Freeze IK
• Lipsync

In case this raised your interest, consider following my YouTube channel for future devlogs + more :).

Best regards,
Kreshi

1 Like

Devlog #1 has been released :).

Check it out:



1 Like

Looks cool!

1 Like

Devlog #2 which is a short one has been released today and comes with a free script!

Progress includes:

  • Controller functionality added
  • Improved aiming with the axe
  • Improved hit detection by switching from trigger-based collisions to raytraced collision

Free Script:

using System;
using System.Collections.Generic;
using UnityEngine;

namespace HoaxGames
{
    public class RaytraceCollision : MonoBehaviour
    {
        [SerializeField] protected LayerMask m_raycastLayerMask;
        [SerializeField] protected QueryTriggerInteraction m_raycastQueryTriggerInteraction = QueryTriggerInteraction.Ignore;
        [SerializeField] protected int m_maxTraceCount = 5;
        [SerializeField] protected float m_minRayDistance = 0.05f;
        [SerializeField] protected bool m_useSphereCast = false;
        [SerializeField] protected float m_spereCastRadius = 0.2f;
        [SerializeField] protected bool m_debugDrawTrace = false;

        // subscribe to onHit with += your function to receive the corresponding hits detected by this class
        public Action<HashSet<RaycastHit>> onHit;

        public class Trace
        {
            public Trace(Transform _transform)
            {
                transform = _transform;
            }

            public Transform transform;
            public Queue<Vector3> tracePoints = new Queue<Vector3>();
        }

        protected List<Trace> m_traces = new List<Trace>();
        protected HashSet<RaycastHit> m_hits = new HashSet<RaycastHit>();
        protected HashSet<Transform> m_hitTransforms = new HashSet<Transform>();

        private void Awake()
        {
            for (int i = 0; i < transform.childCount; i++)
            {
                m_traces.Add(new Trace(transform.GetChild(i)));
            }
        }

        private void OnEnable()
        {
            m_hits.Clear();
            m_hitTransforms.Clear();

            foreach (Trace trace in m_traces)
            {
                while(trace.tracePoints.Count > 0)
                {
                    trace.tracePoints.Dequeue();
                }
            }
        }

        // Start is called before the first frame update
        void Start()
        {
#if !UNITY_EDITOR
            m_debugDrawTrace = false;
#endif
        }

        // Update is called once per frame
        void Update()
        {
            if (onHit != null || m_debugDrawTrace)
            {
                if(m_hits.Count > 0)
                {
                    m_hits.Clear();
                    m_hitTransforms.Clear();
                }

                foreach (Trace trace in m_traces)
                {
                    trace.tracePoints.Enqueue(trace.transform.position);
                    if (trace.tracePoints.Count > m_maxTraceCount) trace.tracePoints.Dequeue();

                    computeHitsFromTrace(trace);
                }

                if (onHit != null) onHit(m_hits);
            }
        }

        void computeHitsFromTrace(Trace trace)
        {
            Vector3 startPos = Vector3.zero;
            bool isInitialized = false;
            foreach (Vector3 currPos in trace.tracePoints)
            {
                if (isInitialized == false)
                {
                    startPos = currPos;
                    isInitialized = true;
                    continue;
                }

                Vector3 distVec = currPos - startPos;
                if (distVec.magnitude < m_minRayDistance) continue;

#if UNITY_EDITOR
                if (m_debugDrawTrace) Debug.DrawLine(startPos, currPos, Color.yellow);
#endif

                RaycastHit[] hits;
                if (m_useSphereCast == false)
                {
                    Ray ray = new Ray(startPos, distVec.normalized);
                    hits = Physics.RaycastAll(ray, distVec.magnitude, m_raycastLayerMask, m_raycastQueryTriggerInteraction);
                }
                else
                {
                    Ray ray = new Ray(startPos - distVec.normalized * m_spereCastRadius, distVec.normalized);
                    hits = Physics.SphereCastAll(ray, m_spereCastRadius, distVec.magnitude, m_raycastLayerMask, m_raycastQueryTriggerInteraction);
                }

                foreach (RaycastHit hit in hits)
                {
                    if (hit.transform == null) continue;
                    if (m_hitTransforms.Contains(hit.transform) == false)
                    {
                        m_hits.Add(hit);
                        m_hitTransforms.Add(hit.transform);
                    }
                }

                startPos = currPos;
            }
        }
    }
}